Authentication
How app service-auth, buyer assertions, dashboard sessions, and OAuth grants fit together.
Compatible with the closed-beta ATM app APIs and versioned ATM event headers. Check atm-api-version on every webhook or XRPC receiver event.
The four auth types
| Auth type | Who mints it | What it proves | What it does not prove |
|---|---|---|---|
| Dashboard session | ATM browser OAuth | A human is signed into ATM dashboard. | App server authority. |
| App service-auth JWT | App DID or PDS | A registered app is calling an ATM XRPC method. | Buyer consent. |
| Buyer assertion | Buyer DID through the app | The app saw this signed-in buyer for this action. | ATM PDS write permission. |
| OAuth grant | User to ATM or app | The grantee may write allowed records to the user's repo. | Payment settlement. |
Buyer checkout assertion
A signed-in buyer should not need to sign into ATM again just to pay. The originating app can pass a short-lived buyer assertion inside the private checkout envelope. ATM verifies the assertion and stores private verification metadata.
- 01
Buyer signs into app
The app has a normal user session.
- 02
App requests user service-auth
The assertion is scoped to the ATM payer assertion method.
- 03
App creates checkout
The envelope includes buyerDid plus buyerAssertionJwt.
- 04
ATM verifies assertion
ATM records that the payer was asserted without receiving an OAuth grant.
- 05
Proof upgrade later
A strict payer proof can still be written later by app delegation or ATM OAuth.
App-originated checkout
The app DID is authenticated separately from the buyer. ATM uses the app identity for module access, fee attribution, webhook routing, environment scoping, and app-visible payment rows.
- 01
App server builds envelope
Private checkout context stays off public PDS records.
- 02
App mints service-auth
iss is the app DID and lxm is network.attested.payment.initiate.
- 03
ATM verifies app
ATM checks issuer, audience, method, expiry, signature, and replay state.
- 04
ATM returns checkout URL
Buyer can pay on hosted checkout without another app auth step.
Webhook and XRPC receiver auth
HTTP webhooks are signed with the app environment secret. XRPC receiver callbacks invert the auth direction: ATM calls the app's receiver with ATM service-auth, and the app verifies ATM as the caller.
- 01
ATM creates event
The event includes environment and delivery ids.
- 02
HTTP webhook
ATM signs the raw body with the app environment secret.
- 03
XRPC receiver
ATM sends service-auth to the app-hosted XRPC method.
- 04
App deduplicates
The app stores delivery id before side effects.
App service-auth
App-facing XRPC calls require a short-lived service-auth JWT. ATM derives the app identity from the verified JWT issuer, not from a loose browser parameter. That protects fee attribution, webhook routing, module access, and app dashboard visibility.
iss = app DID
aud = ATM broker/service audience
lxm = exact XRPC method NSID
jti = unique per request
exp = short-livedBuyer assertions
When an app already has the buyer signed in, it can include a short-lived buyer service-auth assertion in private checkout or ticket requests. This proves the app saw that buyer at action time without asking the buyer to re-auth in ATM checkout.
Buyer assertions are not OAuth grants. They let ATM mark private ledger rows as payer-asserted, but they do not let ATM write to the buyer's PDS. Strict public payer proofs still require a payer-owned write through app delegation or an ATM OAuth grant.
OAuth grants
OAuth grants are used when ATM or an app needs to write AT Protocol records to a user's repo. For normal checkout, avoid prompting for OAuth again just to improve proof mode. Use the buyer assertion pattern where the app already has the buyer present.