OpenApe Grants
OpenApe Grants
@openape/grants
The permission engine. Framework-agnostic. This package provides the core grant lifecycle, AuthZ-JWT issuance, and verification β independent of any framework.
Grant Lifecycle
Request β Pending β Approved/Denied β (if approved) Active β Used/Expired/Revoked
Grant Types
| Type | Behavior | AuthZ-JWT Lifetime | Reusable? |
|---|---|---|---|
once | Single use β consumed after first use | 5 minutes | No |
timed | Valid for a time window (TTL) | Until expires_at | Yes |
always | Standing permission β active until revoked | 1 hour (renewable) | Yes |
For timed grants, specify a duration in seconds when requesting. For always grants, the AuthZ-JWT expires after 1 hour but can be re-fetched as long as the grant is not revoked.
AuthZ-JWT
On approval, a signed AuthZ-JWT is issued:
{
"iss": "https://id.example.com",
"sub": "agent@example.com",
"aud": "target-system",
"target_host": "prod-server.example.com",
"grant_id": "uuid",
"grant_type": "once",
"permissions": ["deploy"],
"command": ["systemctl", "restart", "nginx"],
"cmd_hash": "sha256:a1b2c3...",
"decided_by": "alice@example.com",
"exp": 1234567890,
"jti": "unique-grant-id"
}
Key security features:
audbinding β token only valid for the intended target servicetarget_hostβ restricts to a specific hostcmd_hashβ binds to exact command (prevents substitution attacks)decided_byβ dual accountability (agent identity β approver identity)jtiβ replay protection- Expiry β all grants have a maximum lifetime
Grant Request Fields
| Field | Required | Description |
|---|---|---|
requester | Yes | Agent email (auto-set if using agent token) |
target_host | Yes | Host where the grant is valid |
audience | Yes | Service identifier (e.g., escapes, proxy) |
grant_type | No | once (default), timed, or always |
command | No | Command array (e.g., ["apt-get", "upgrade"]) |
permissions | No | Permission strings |
duration | For timed | Duration in seconds |
reason | No | Human-readable reason for the request |
run_as | No | Execute as this user |
Grant Routes in @openape/nuxt-auth-idp
Grant management is integrated into @openape/nuxt-auth-idp. Enable grant pages with grants.enablePages: true in your module config.
@openape/nuxt-grants is deprecated. All grant functionality has been consolidated into @openape/nuxt-auth-idp.Auto-registered API routes:
POST /api/grantsβ create grant requestGET /api/grantsβ list grantsGET /api/grants/:idβ get grant details (supports ETag polling)POST /api/grants/:id/approveβ approve a grant (returns AuthZ-JWT)POST /api/grants/:id/denyβ deny a grantPOST /api/grants/:id/revokeβ revoke an active grantPOST /api/grants/:id/tokenβ get AuthZ-JWT for approved grantPOST /api/grants/:id/consumeβ consume aoncegrantPOST /api/grants/verifyβ verify an AuthZ-JWT
Agent API routes:
POST /api/agent/enrollβ register a new agent (requires Management Token)POST /api/agent/challengeβ request auth challengePOST /api/agent/authenticateβ authenticate with signed challenge
Pages (overridable, enabled via grants.enablePages: true):
/grantsβ grant dashboard/grant-approvalβ approve/deny UI/enrollβ agent enrollment form
For detailed request/response schemas, see the Agent Integration Guide.
Agent Tools
The following tools use the grant system for access control:
| Tool | Purpose | Docs |
|---|---|---|
| grapes | Universal Grant Management CLI | Request, approve, delegate, execute |
| escapes | Local privilege elevation via AuthZ-JWT | Setuid-root Rust binary |
| @openape/proxy | Agent HTTP gateway with grant-based access rules | Forward proxy |
| @openape/browser | Grant-aware headless browser | Playwright wrapper |
| @openape/shapes | Grant-aware CLI wrappers | Adapters for kubectl, aws, etc. |