Skip to content

0016: Shorten expiration time and add revocation method - #109

Open
dholms wants to merge 2 commits into
mainfrom
0016/expiration-and-revocation
Open

dholms wants to merge 2 commits into
mainfrom
0016/expiration-and-revocation

Conversation

@dholms

@dholms dholms commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

I think non-revocable 2 hour credentials are probably a little too dicey.

This shortens the default expiration to 10 minutes, and introduces a method for space authorities to revoke particular credentials (by jti). I expect revocation will not be used in most cases, but it is a useful lever to have around when needed. The primary cost is fanning out the revocation which is primarily paid by the space authority.

@bnewbold

bnewbold commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

This is going to interact a bit funny with app services which have multiple authorized user accounts, and they are choosing which space credential to use somewhat arbitrarily. The app service will need to figure out if access was denied because an individual user was removed (and the app can get a new space credential from a different user session), or the entire app itself is locked out. The later also only makes sense if client attestation is required. This isn't intractable, just some extra complexity and logic.

Using the nonce feels a bit weird, but I can't think of what else we'd use: hash of the overall token?

Space host will need to keep track of outstanding nonces for credentials it has issued, tied back to user account, space, and (optional) client_id. The space host is likely to have all that info persisted in a database already, so the privacy hit isn't too bad for authorities that chose to implement this (but isn't zero).

A possible alternative would be to use iat as the revocation signal. The space host would basically say "hey reject any space credentials for this entire space issued before just now". This would force all readers/syncers to refresh their space credential, but would be a bit less state for the repo host or space host to need to retain (doesn't need to keep track of jti).

I'm not sure that is really better, just tossing it out.

@dholms

dholms commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

The app service will need to figure out if access was denied because an individual user was removed

Yeah that's true. I don't see a big issue with that though. It's no different from determining which OAuth sessions they can use to get space credentials in the first plaace.

Using the nonce feels a bit weird, but I can't think of what else we'd use: hash of the overall token?

This is one of the intended uses of the jti field. It stands for "JWT ID" so isn't just a nonce.

A possible alternative would be to use iat as the revocation signal.

This is too broad of an alternative IMO. It's unfortunate to have to revoke every credential when you really just want to revoke one.

@bnewbold

bnewbold commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

I do think these are good changes and the design questions aren't major, so i'm going to mark approved.

But putting more thoughts below in case we come back to this later.

This is one of the intended uses of the jti field. It stands for "JWT ID" so isn't just a nonce.

TIL!

Yeah that's true. I don't see a big issue with that though. It's no different from determining which OAuth sessions they can use to get space credentials in the first place.

I don't think it is an argument against these changes. It does make me more nervous about that "which session to use" tangle. As much of a "how do we communicate this whole situation to devs and make sure they don't do it some weird broken way" as anything. Maybe sidecar service will solve this for most devs, but probably not all.

This is too broad of an alternative IMO. It's unfortunate to have to revoke every credential when you really just want to revoke one.

The common case is going to be revoking all space credentials for the tuple of (account, space), because they have been removed from the space, right? In that case you want to hit "all" space credentials. Likely there will be only one outstanding (or zero), so not a huge deal, but in some cases would need to send repeated individual revocations. Having to do extra database hits to check token IDs individually (instead of a per-account timestamp) is maybe extra I/O also, but likely trivial.


Short expiration is the primary revocation mechanism for space credentials. When an authority stops authorizing an application, or the application no longer has any authorized user's session available, it can no longer obtain replacement credentials and its outstanding credentials expire after their remaining lifetime (generally 10 minutes).

For cases that faster revocation, an authority MAY send `com.atproto.space.notifyCredentialRevoked` to repo hosts serving repos in the space. The notification identifies one or more outstanding credentials by `jti`. A repo host MUST reject a credential whose `jti` has been revoked for that space and retain the revocation for at least 60 minutes, after which no credential with that `jti` can remain valid. The method is authenticated with service auth from the space authority.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For cases that faster revocation, an authority MAY send `com.atproto.space.notifyCredentialRevoked` to repo hosts serving repos in the space. The notification identifies one or more outstanding credentials by `jti`. A repo host MUST reject a credential whose `jti` has been revoked for that space and retain the revocation for at least 60 minutes, after which no credential with that `jti` can remain valid. The method is authenticated with service auth from the space authority.
For cases that call for faster revocation, an authority MAY send `com.atproto.space.notifyCredentialRevoked` to repo hosts serving repos in the space. The notification identifies one or more outstanding credentials by `jti`. A repo host MUST reject a credential whose `jti` has been revoked for that space and retain the revocation for at least 60 minutes, after which no credential with that `jti` can remain valid. The method is authenticated with service auth from the space authority.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants