This document defines an authentication suite for the Linked Web Storage (LWS) protocol, enabling clients that are able to sign their own identity tokens to integrate with LWS.
This is an unofficial proposal.
Self-issued identity is important for cases where applications act on their own behalf. This includes autonomous bots as well as server-side scripts, among others. In these cases, the agent is able to securely manage the private portion of a keypair, which it uses to generate signed JSON Web Tokens (JWT). This specification describes how this class of agents can generate authentication credentials that can be used with a Linked Web Storage.
The terms "authorization server" and "client" are defined by The OAuth 2.0 Authorization Framework [[!RFC6749]].
The terms "controlled identifier document" and "verification method" are defined by W3C Controlled Identifiers 1.0 [[!CID-1.0]].
The terms "JSON Web Token (JWT)" and "claim" are defined by JSON Web Token [[!RFC7519]].
The terms "agent", "authentication credential", and "authentication suite" are defined by Linked Web Storage Protocol [[!LWS10-CORE]]
A self-issued authentication credential is serialized as a signed JSON Web Token (JWT). In order to use a JWT as an LWS authentication credential, the following additional requirements apply.
The JWT MUST NOT use "none" as the signing algorithm.
The JWT MUST use the sub (subject) claim for the LWS subject identifier.
The JWT MUST use the iss (issuer) claim for the LWS issuer identifier.
The JWT MUST use the client_id (client ID) claim for the LWS client identifier.
The claims sub, iss, and client_id MUST all use the same URI value.
Any audience restriction in the ID Token MUST use the aud (audience) claim. The aud claim MUST include the target authorization server.
The JWT MUST include an exp (expiration) claim, indicating the time the token expires.
The JWT MUST include an iat (issued at) claim, indicating the time the token was issued.
An example JWT that is also an LWS authentication credential is included below.
{
"kid": "c1f52577",
"kty": "EC",
"alg": "ES256",
"typ": "JWT",
"crv": "P-256"
}
.
{
"sub": "https://id.example/agent",
"iss": "https://id.example/agent",
"client_id": "https://id.example/agent",
"aud": ["https://as.example"],
"iat": 1761313600,
"exp": 1761313900
}
.
signature
In order to validate a JWT as an LWS authentication credential, there must be a trust relationship between the verifier and the issuing party.
In the absence of a pre-existing trust relationship, the verifier MUST dereference the sub (subject) claim in the authentication credential.
The resulting resource MUST be formatted as a valid controlled identifier document [[!CID-1.0]] with an id value equal to the subject identifier.
A verifier MUST reject any tokens using an alg header parameter that equals "none".
A verifier MUST validate all claims described by the authentication credential data model.
The verifier MUST use the kid (key id) value from the signed JWT header to identify a verification method from the subject's controlled identifier document.
This process is described in [[!CID-1.0]] Section 3.3.
Using the selected verification method from the controlled identifier document, the signature of the JWT MUST be validated as described in [[!RFC7515]], Section 5.2.
A verifier MUST ensure that the current time is before the time represented by the exp claim. Implementers MAY provide for some small leeway to account for clock skew.
An example Controlled Identifier Document is included below.
{
"@context": [
"https://www.w3.org/ns/cid/v1" ],
"id": "https://id.example/agent",
"authentication": [{
"id": "https://id.example/agent#c1f52577",
"type": "JsonWebKey",
"controller": "https://id.example/agent",
"publicKeyJwk": {
"kid": "c1f52577",
"kty": "EC",
"crv": "P-256",
"alg": "ES256",
"x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
"y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"
}
}]
}
A self-issued JSON Web Token used as an authentication credential MUST use the urn:ietf:params:oauth:token-type:jwt URI when interacting with an authorization server.
All security considerations described in "Best Current Practice for OAuth 2.0 Security" [[RFC9700]] and "OpenID Connect Core 1.0" Section 16 [[OPENID-CONNECT-CORE]] apply to this specification.
A self-issued authentication credential uses a subject identifier that
is both persistent and globally unique. Because the sub,
iss, and client_id claims all share the same URI value,
verifiers and storage servers can correlate all activity from a given agent
across sessions and resources.
The validation process requires dereferencing the subject identifier to retrieve a controlled identifier document. This dereference operation can reveal to the hosting server of that document which verifiers are validating credentials for a given agent, including timing and frequency of access. Verifiers are encouraged to cache controlled identifier documents to reduce unnecessary network requests and the associated metadata leakage.
Because the controlled identifier document contains the public key material used for validation, the hosting server of that document is in a position to observe which keys are being actively used. Agents that require stronger privacy guarantees are encouraged to host their controlled identifier documents on infrastructure they control.
Self-issued tokens presented to a storage server or authorization server can be read by those parties. The use of TLS is essential for protecting authentication credentials during transmission.