Ecosystem

OpenApe Grants

Human-in-the-loop permissions for agents.

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

TypeBehaviorAuthZ-JWT LifetimeReusable?
onceSingle use β€” consumed after first use5 minutesNo
timedValid for a time window (TTL)Until expires_atYes
alwaysStanding permission β€” active until revoked1 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:

  • aud binding β€” token only valid for the intended target service
  • target_host β€” restricts to a specific host
  • cmd_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

FieldRequiredDescription
requesterYesAgent email (auto-set if using agent token)
target_hostYesHost where the grant is valid
audienceYesService identifier (e.g., escapes, proxy)
grant_typeNoonce (default), timed, or always
commandNoCommand array (e.g., ["apt-get", "upgrade"])
permissionsNoPermission strings
durationFor timedDuration in seconds
reasonNoHuman-readable reason for the request
run_asNoExecute 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 request
  • GET /api/grants β€” list grants
  • GET /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 grant
  • POST /api/grants/:id/revoke β€” revoke an active grant
  • POST /api/grants/:id/token β€” get AuthZ-JWT for approved grant
  • POST /api/grants/:id/consume β€” consume a once grant
  • POST /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 challenge
  • POST /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:

ToolPurposeDocs
grapesUniversal Grant Management CLIRequest, approve, delegate, execute
escapesLocal privilege elevation via AuthZ-JWTSetuid-root Rust binary
@openape/proxyAgent HTTP gateway with grant-based access rulesForward proxy
@openape/browserGrant-aware headless browserPlaywright wrapper
@openape/shapesGrant-aware CLI wrappersAdapters for kubectl, aws, etc.