Support

We're here to help you get the most out of Truestamp. Find answers to common questions or get in touch with our support team.

Community & Updates

Share feedback, follow what we're building next, and see what just shipped. Each opens right here in a popup, so no separate account is needed.

Knowledge Base

Browse the concepts behind Truestamp. Pick a domain to explore, follow the links between concepts, or search across everything.

OAuth 2.1 Authorization Server

Truestamp's OAuth 2.1 authorization server with authorize, token, register, and revoke endpoints, RFC 8414/9728 discovery documents, PKCE S256, audience-bound tokens, rotating refresh tokens, and per-surface mcp/api/console scopes for authenticating a CLI or MCP agent.

Overview

Truestamp runs a standards-compliant OAuth 2.1 authorization server so a client such as the truestamp CLI or an LLM agent connector (Claude Code, Claude.ai) can obtain delegated, user-consented, scoped access to your account without you handing over a password or a long-lived API key. A client runs the authorization-code flow with PKCE: it sends you to a branded consent screen, receives a short-lived authorization code at a redirect URI, and exchanges that code for an access token plus a rotating refresh token. Access tokens are bound to a single audience (the Truestamp origin) and carry per-surface scopes that say what the token may do. The whole server is enabled by default and can be turned off globally by an administrator with a single kill-switch. When it is off, every OAuth route returns 404.

Endpoints and discovery

The authorization server exposes four protocol endpoints plus a set of well-known discovery documents. All paths are relative to https://www.truestamp.com.

Method Path Purpose
GET/POST /oauth/authorize user consent and authorization-code issuance (browser)
POST /oauth/register dynamic client registration
POST /oauth/token exchange an authorization code or a refresh token for tokens
POST /oauth/revoke revoke a refresh token
GET /.well-known/oauth-authorization-server authorization-server metadata (RFC 8414)
GET /.well-known/oauth-protected-resource protected-resource metadata (RFC 9728)
GET /.well-known/openid-configuration OIDC-tooling alias for the AS metadata

A client never needs these paths hard-coded. It fetches the well-known authorization-server document and reads the authorize, token, register, and revoke URLs from it. The protocol endpoints under /oauth/* are unauthenticated by design (the token endpoint’s proof is PKCE and the code, not a client secret) and are per-IP rate limited. The consent step at /oauth/authorize runs in the browser and requires you to be signed in. If you have a second authentication factor (TOTP) configured, you must complete it in your session before you can approve a grant.

Registering a client

Clients are public and PKCE-only: there is no client secret, so the per-flow PKCE verifier is the only secret. There are two ways a client gets a client_id.

  • Dynamic Client Registration. An agent connector self-registers by POSTing to /oauth/register with a client_name and redirect_uris before any user-facing flow begins. Registration is open (no initial access token), because MCP-style clients must register before they can send you to consent. Your protection lives downstream in the consent screen, PKCE, exact redirect-URI matching, and audience-bound tokens.
  • A pre-registered first-party client. The truestamp CLI ships a fixed, well-known client_id baked into its binary with fixed loopback redirect URIs (http://127.0.0.1:8976/callback and http://127.0.0.1:8765/callback), so it does not need to self-register.

A registered client records the redirect_uris, grant_types, response_types, and requested scope it will use. The redirect URI is matched exactly at both /oauth/authorize and /oauth/token; an unregistered redirect_uri produces an error page rather than a redirect.

Authorization-code flow with PKCE

The flow a CLI or agent runs is authorization-code plus PKCE with a loopback redirect, which is the correct pattern for a public native client.

  1. Generate PKCE. The client creates a random verifier and its SHA-256 challenge, plus a state value. Only the S256 challenge method is accepted; the plain method is rejected.
  2. Start the flow. The client opens your system browser to /oauth/authorize with response_type=code, its client_id, the redirect_uri, code_challenge, code_challenge_method=S256, the requested scope, and state. A CLI first starts a small local HTTP listener on its loopback redirect port.
  3. Consent. You sign in (and complete your second factor if needed) and approve the client name, scopes, and redirect target on the Truestamp consent screen. If you have already consented to this client at a scope that covers the request, the screen is skipped.
  4. Receive the code. The server redirects to the client’s redirect_uri with a short-lived, single-use authorization code and the state. The client verifies state.
  5. Exchange. The client POSTs to /oauth/token with the code and the PKCE verifier. The server checks the verifier against the stored challenge and, on success, returns an access token and a refresh token.
  6. Use and refresh. The client sends the access token as Authorization: Bearer <token> and uses the refresh token to mint a new access token when the old one expires.

Authorization codes are single-use: a code that is exchanged a second time is rejected, so a stolen-then-replayed code fails.

Tokens, lifetimes, and refresh

Both grant types are handled at /oauth/token: authorization_code for the initial exchange and refresh_token for renewal.

  • Access token: 24 hours. This is deliberately longer than the more common one hour. Some agent clients abandon a still-valid refresh token after a long idle and force a full re-authorization instead of refreshing, so a day-long access token lets an overnight agent session keep working on the access token alone.
  • Refresh token: 30 days, rotating. Each refresh returns a fresh access token and a new refresh token; the old refresh token is retired. Refresh tokens are stored only as SHA-256 hashes. Reusing an already-rotated refresh token trips reuse detection and revokes the entire rotation chain, surfacing a compromise.
  • Authorization code: 10 minutes. Short-lived and single-use.

The OAuth-correct renewal path is the refresh_token grant: when an access token expires, the client silently exchanges its refresh token for a new access token with no user interaction. Revocation of a refresh token (via /oauth/revoke, or by deleting your consent) invalidates that chain, though an already-minted access token remains valid until it expires because access tokens are not individually revocable before expiry.

Scopes per surface

Capability is differentiated by scope, not by audience: every token shares one origin-wide audience, and the scopes on it decide what surfaces it may reach. The server advertises six scopes, a read and a write per surface. A client that requests any scope outside this set is rejected at /oauth/authorize before you see a consent screen.

Scope Grants
mcp:read read access on the MCP server
mcp:write writes composed in an MCP script (item and team creation)
api:read JSON:API and GraphQL reads
api:write JSON:API and GraphQL mutations
console:read open the console WebSocket and read or stream
console:write console write commands

Request the narrowest scope your client needs. For a read-only integration over the REST API, api:read is enough (the read-only beacon API is a natural first authenticated call for smoke-testing a new grant); a CLI that also writes requests api:read api:write. Scope enforcement applies only to a delegated OAuth grant. An API key is not scope-limited, so scope checks are a no-op for API-key callers. The same origin-wide audience means an api:* token issued by this server works against the REST API today.

Which surfaces accept an OAuth token

An OAuth access token authenticates all four Truestamp API surfaces. Three of them accept an OAuth bearer token or an API key interchangeably, and existing API keys keep working unchanged.

  • MCP (/mcp) is OAuth-only. It is an OAuth protected resource and does not accept API keys. A missing, invalid, or expired token returns 401 with a WWW-Authenticate: Bearer resource_metadata="..." header pointing at the protected-resource metadata document. That challenge is the discovery linchpin: an agent harness reads it, self-registers, and runs the PKCE flow automatically. See the MCP server for LLM agents concept for the tool catalog and the confirm-before-write flow.
  • JSON:API, GraphQL, and the console WebSocket each accept an Authorization: Bearer credential that is either an OAuth access token or an API key. These surfaces already required authentication; OAuth is an additional accepted credential, not a new public path.

Activation and kill switch

The authorization server is enabled by default, and an administrator can disable the entire surface globally on demand. While it is disabled, every /oauth/* route and every /.well-known/oauth-* discovery document returns 404, so OAuth clients treat the server as absent and stop attempting the flow. Because MCP depends on the OAuth surface, disabling OAuth also makes /mcp unavailable; the other three surfaces fall back to API-key-only authentication.

Security properties

  • PKCE, S256 only. The plain challenge method is never accepted, and the verifier is checked at the token endpoint.
  • Audience binding. Every access token is bound to the Truestamp origin as its audience, so a token minted by another deployment (for example staging) is rejected here.
  • Exact redirect-URI matching. No normalization, so an unregistered redirect URI cannot be used to leak a code (no open redirect).
  • Refresh rotation with reuse detection. Single-use refresh tokens; reusing a rotated token revokes the whole chain.
  • Second-factor gate on consent. If you have a second authentication factor (TOTP) configured, you cannot approve a grant until you have verified it in your session.
  • Scoped, per-client consent. You see and approve the client name, the redirect target, and the exact scopes before any token is issued.

Citations

  1. RFC 6749: The OAuth 2.0 Authorization Framework. Base authorization-code grant and token endpoint semantics that OAuth 2.1 refines.
  2. RFC 7636: Proof Key for Code Exchange (PKCE). The S256 code-challenge mechanism used in place of a client secret.
  3. RFC 7591: OAuth 2.0 Dynamic Client Registration Protocol. The /oauth/register self-registration used by agent connectors.
  4. RFC 8707: Resource Indicators for OAuth 2.0. Audience-bound access tokens.
  5. RFC 8414: OAuth 2.0 Authorization Server Metadata. The /.well-known/oauth-authorization-server discovery document.
  6. RFC 9728: OAuth 2.0 Protected Resource Metadata. The /.well-known/oauth-protected-resource document and the WWW-Authenticate challenge.
  7. RFC 7009: OAuth 2.0 Token Revocation. The /oauth/revoke endpoint.
  8. RFC 8252: OAuth 2.0 for Native Apps. The loopback-redirect authorization-code plus PKCE pattern used by a CLI.

Get Help

API Documentation

Comprehensive guides for the REST and GraphQL APIs, including interactive documentation and code examples.

View API Docs

FAQ

Quick answers to the most commonly asked questions about timestamping and verification.

Browse FAQ

Email Support

Send us a message and our team will respond within 24 hours.

[email protected]

Security Issues

Report security vulnerabilities through our responsible disclosure program.

[email protected]