feat(identity)!: resolver abstraction, identity caching and SSRF-safe fetching #120
Labels
No labels
breaking-change
bug
documentation
duplicate
enhancement
good first issue
help wanted
performance
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Grandiras/ATProto.NET#120
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Part of the v0.7.0 update cycle (wave 4). DID and handle resolution is uncached, has no abstraction, is written three times, and is not SSRF-hardened. The worst consequence:
FirehoseVerifierresolves the DID document over HTTP for every commit, so a signature-verifying firehose consumer handles about 10–30 commits/s against a 1–2k/s firehose, and it hammers plc.directory.Abstraction
IDidResolver,IHandleResolverandIIdentityResolver(bidirectional handle verification, withhandle.invalidon failure), returningResolvedIdentity(Did, Handle?, HandleVerified, Uri? PdsEndpoint, DidDocument).DidDocument. Delete the OAuth copy (Auth/OAuth/OAuthModels.cs) and the duplicateDidServicetypes. ProvideGetServiceEndpoint(fragment, type?),GetVerificationKey(fragment)and a validatedGetHandle().plc.directory),FirehoseVerifier,SpaceCredentialProvider,SpaceSyncer, the Spaces server resolvers andSpaceAuthority.DidResolutionException(kind)replacesPlcException/DidWebException. TodayPlcExceptionescapes the Spaces error contracts.Caching
Invalidate(did), and an optionalIDistributedCachebacking. It replacesCachingSpaceDidDocumentResolver, which is unbounded, has no negative cache and no single-flight.TypedFirehoseConsumerinvalidates on#identityevents.SpaceServiceAuthVerifier.IsRepoHostAsyncresolves its two DIDs concurrently.Hardened fetching (SSRF)
One policy for every identity fetch (did:web, PLC,
.well-known/atproto-did):httpsonly;SocketsHttpHandler.ConnectCallbackrejecting loopback/private/link-local/CGNAT addresses after DNS;Today the two DID resolvers disagree: the one the space server uses accepts any
host:port, for exampledid:web:internal.corp%3A6379.Handle resolution: DNS TXT (a configurable DoH endpoint; today it is hard-coded to
dns.google) plus HTTPS well-known, keeping the current fail-closed-on-conflict semantics.Lexicon and PLC
com.atproto.identity.resolveIdentity,resolveDidandrefreshIdentity(+defs#identityInfo).PlcClienttakes anHttpClientplus an explicit directory URL (it relies onBaseAddresstoday). Keep the audit, log, data and health APIs and add tests for them. Add PLC/exportand the/export/streamWebSocket.PlcOperationService=DidService,PlcData⊂PlcOperation, …).Acceptance
Breaking changes(moved and renamed types, the exception type),Security(SSRF),Changed(caching).