feat: Agent runtime token system — Phase 1 (token CRUD)#853
Merged
Conversation
Add per-agent bearer tokens for runtime authentication. This is Phase 1 of the agent runtime auth system (issue #740) — token CRUD without the auth middleware (Phase 2). Database (AgentTokens.php): - datamachine_agent_tokens table: token_id, agent_id, token_hash, token_prefix, label, capabilities, last_used_at, expires_at - Tokens stored as SHA-256 hashes — raw token only returned on create - Token format: datamachine_{agent_slug}_{64_hex_chars} - create_token(), resolve_token(), revoke_token(), list_tokens() - revoke_all_for_agent() for agent deletion cleanup - touch_last_used() for activity tracking Abilities (AgentTokenAbilities.php): - datamachine/create-agent-token: validates agent exists/active, checks admin access, generates crypto-random token, returns raw token once with warning to save it - datamachine/revoke-agent-token: admin access check, agent ownership validation, immediate invalidation - datamachine/list-agent-tokens: operator+ access, returns metadata only (never token hashes) CLI (AgentsCommand.php): - wp datamachine agents token create <slug> --label=... --expires-in=... - wp datamachine agents token list <slug> - wp datamachine agents token revoke <slug> <token_id> - Prominent warning on create: save the token, it cannot be retrieved REST (Agents.php): - POST /agents/{id}/tokens — create token - GET /agents/{id}/tokens — list tokens - DELETE /agents/{id}/tokens/{token_id} — revoke token - All thin wrappers over AgentTokenAbilities Bootstrap (data-machine.php): - AgentTokens::create_table() in activation - AgentTokenAbilities in abilities initialization Phase 2 (separate PR) will add AgentAuthMiddleware that resolves these tokens on incoming requests, sets agent context, and enforces the capability ceiling.
Homeboy Results —
|
This was referenced Mar 18, 2026
Add the runtime authentication layer that resolves agent bearer tokens
into scoped execution contexts with capability ceilings.
AgentAuthMiddleware (new file):
- Hooks rest_authentication_errors at priority 90
- Only intercepts Authorization: Bearer datamachine_* tokens
- hash(token) → AgentTokens::resolve_token() lookup
- Validates: token not expired, agent active, owner user exists
- wp_set_current_user(owner_id) — WP sees the owner for cap checks
- PermissionHelper::set_agent_context() — sets agent scoping layer
- Updates last_used_at on every successful auth
- Non-matching tokens pass through to WP's normal auth chain
PermissionHelper modifications:
- New static properties: acting_agent_id, agent_owner_id,
agent_token_capabilities
- set_agent_context() / clear_agent_context() / get_acting_agent_id()
/ in_agent_context() — agent context lifecycle
- agent_can() — enforces capability ceiling:
1. Token capability restrictions (if set, action must be in list)
2. Owner WP capability check (ceiling — agent never exceeds owner)
- can() now checks agent context before pre-auth and standard paths
- acting_user_id() returns owner's user_id in agent context
Three nested permission ceilings:
owner WP role (e.g., Editor)
∩ agent tool policy (ToolPolicyResolver, already built)
∩ token capabilities (per-token restrictions)
= effective permissions
Closes #854, closes #855
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Why This Matters
This sets the foundation for "every user on a site can have their own AI agent":
Token Design
datamachine_{agent_slug}_{64_random_hex_chars}datamachine_agent_tokenswithtoken_hashUNIQUE index for O(1) lookupslast_used_attrackingNew Surfaces
CLI
REST API
POST/agents/{id}/tokensGET/agents/{id}/tokensDELETE/agents/{id}/tokens/{token_id}Abilities
datamachine/create-agent-tokendatamachine/revoke-agent-tokendatamachine/list-agent-tokensPhase 2 (Next PR)
AgentAuthMiddleware: hooksrest_authentication_errors, resolves bearer token → agent contextPermissionHelper::set_agent_context(): sets acting agent + capability ceilingCloses
Partially addresses #740 (Phase 1 of multi-phase implementation)