Access policy and token expiry
Admins can set Settings → Access policy to a maximum token lifetime of 1 to 730 days, or remove the cap. Mint requests acceptexpires_in_days (a positive whole number of days). With a cap, omitting it or exceeding the cap returns HTTP 400 token_lifetime_exceeds_policy. The console expiry selector stays within that cap, including the first token when creating an agent.
Tokens record created_by, the minting member’s user ID, and expires_at, an ISO timestamp or null. Token lists show Made by and expiry; older tokens have no recorded minter. Expired tokens return HTTP 401 access_token_expired, with the same error shape as revocation. Queued work and compute goals also check expiry before execution. Running jobs finish.
Setting a cap does not change existing tokens. Policy responses include active_tokens_without_expiry and active_tokens_exceeding_cap so admins can rotate them. These counts exclude revoked, expired and OAuth tokens; exceeding the cap means the original lifetime from mint to expiry exceeds the cap. Without a cap, the exceeding count is zero. Policy changes are audited as org.access_policy_changed in the organization’s audit log.
OAuth bridge tokens (source = 'oauth') are re-derived by ensureOAuthBridgeToken and exempt from the cap. Standalone wallet and internal mints still allow no expiry.
IP allowlist
Admins can also restrict where the organization’s access tokens are used from: up to 50 IPv4 or IPv6 addresses or CIDR ranges (bare addresses are single hosts). An empty list means no restriction. The policy binds every token of the organization’s agents, including hosted MCP app sign-in tokens, so apps that call from their own servers (connected assistants) stop working unless their ranges are listed. Responses includecaller_ip so an admin can list their own address first.
A token used from an unlisted address gets HTTP 403 ip_not_allowed. The client address is the one the load balancer appended to X-Forwarded-For; prepended entries are ignored. Refusals are audited at most once per token per minute as org.token_ip_refused (group tokens) with the token prefix and address. Wallet-signed and soul-key calls are unaffected.
Responses use
{ success: true, data: { max_token_lifetime_days, token_ip_allowlist, active_tokens_without_expiry, active_tokens_exceeding_cap, caller_ip } }. A body without token_ip_allowlist keeps the saved list; null or [] clears it. Invalid caps return 400 invalid_token_lifetime_days, invalid lists 400 invalid_token_ip_allowlist, invalid lifetimes 400 invalid_expires_in_days. The audit entry carries old and new values of both settings.