atproto_identity 0.1.1
atproto_identity: ^0.1.1 copied to clipboard
AT Protocol identity resolution (handle/DID) and inbound service-auth JWT verification for Dart/Flutter.
Release Note #
0.1.1 #
- docs: documented the
HttpIdentityResolverSSRF/DoS hardening parameters in the README (allowedHosts,allowPrivateNetwork,timeout,maxResponseBytes), explaining whydid:webresolution needs them. - docs: documented the exported
signingKeyOf(didDocument, did)helper and its exact-id matching. - docs: showed
verifyServiceAuth'smaxTokenLifetimein the code sample. - chore: bump
did_plcto^1.1.2.
0.1.0 #
- Initial release.
- feat:
IdentityResolver/HttpIdentityResolverresolve a handle (alice.example, optionally@/at://prefixed) or a DID (did:plc/did:web) to aResolvedIdentity(DID, PDS origin, handle,#atprotosigning key). Handle resolution goes throughcom.atproto.identity.resolveHandleand is verified bidirectionally against the DID document'salsoKnownAs. - feat:
verifyServiceAuthverifies an inbound AppView service-auth JWT from anAuthorization: Bearerheader and returns the issuer (viewer) DID. It validatesaud/exp/lxm/iss, resolves the issuer's#atprotosigning key, and checks the ES256K / P-256 signature viadid_plc. Fails closed: the JWTalgis not trusted, the signature must be a 64-byte compact ECDSA signature, and an out-of-rangeexpis rejected without overflow. - feat:
signingKeyOf(didDocument, did)returns thepublicKeyMultibaseof the#atprotoverification method, ornullwhen absent. - feat:
IdentityExceptionis thrown on any resolution or verification failure. - security:
HttpIdentityResolverhardensdid:webresolution against SSRF and DoS. Private, loopback, link-local, unique-local, multicast, unspecified, and otherwise reserved IP literals (andlocalhost) are rejected by default before any request is issued (allowPrivateNetwork: trueopts out; only IP literals are checked — no DNS resolution is performed, so pair with operator-level egress controls). An optionalallowedHostsallowlist restricts whichdid:webhosts may be contacted at all. Every fetch applies atimeout(default 10s) and amaxResponseBytesbody cap (default 512 KiB), anddid:webredirects are followed manually (max 5), each target re-validated against the host policy and required to behttps. - security:
verifyServiceAuthrejects bearer tokens larger than 8 KiB before any decoding and validates theissclaim against a strict DID grammar (no fragments, queries, paths, or whitespace) before handing it to the resolver. - security:
verifyServiceAuthnow validates the JWT JOSE header before any resolution work: thetyp, when present, must be a JWT media type and thealgmust be one ofES256K/ES256, failing closed onnone, HMAC (HS*), and RSA algorithms (defense in depth — the signing curve is still pinned from the DID document). - security:
verifyServiceAuthbounds the accepted token lifetime. A newmaxTokenLifetimeparameter (default 60 minutes; passnullto opt out) rejects any token whoseexpis implausibly far in the future, and theiat(not in the future) andnbf(not-before) claims are now enforced when present. A 30-second clock-skew allowance is applied consistently toexp/iat/nbf. - security:
signingKeyOfnow matches the#atprotoverification method by exact id (#atprotoor<did>#atproto) instead of aendsWith('#atproto')suffix match, preventing a crafted DID document from smuggling in a key under an id such asdid:plc:x#foo#atproto. - security:
HttpIdentityResolverbinds a fetcheddid:webdocument to the requested DID by asserting itsidequals the DID, rejecting a document that claims to describe a different DID (did:plc remains content-addressed via the trusted PLC directory).