Skip to main content

Migrating from API Keys + Manual Audit

If your agents currently authenticate with static API keys and you log actions manually, Grantex gives you verifiable permissions, automatic audit trails, and user-controlled revocation.

What stays the same

  • Your upstream APIs (Google Calendar, Slack, Stripe, etc.) — agents still call them
  • Your users — they keep their accounts and data
  • Your agent logic — business logic doesn’t change

What changes

  • Auth layer: Static API keys are replaced with scoped, time-bound grant tokens
  • Audit: Manual logging is replaced with tamper-evident, hash-chained audit entries
  • Revocation: Instead of rotating API keys, users revoke grants through a dashboard

Step-by-step

1

Register as a developer

Sign up at the Grantex portal or use the SDK:
const grantex = new Grantex({ baseUrl: 'https://your-auth-service.com' });
const dev = await grantex.developers.register({
  name: 'Acme Corp',
  email: 'dev@acme.com',
});
2

Register your agent

const agent = await grantex.agents.create({
  name: 'Calendar Assistant',
  description: 'Manages calendar events on behalf of users',
  scopes: ['calendar:read', 'calendar:write'],
});
3

Replace API key auth with grant tokens

Before (API key):
// Old: static key, no user consent, no audit
const response = await fetch('/api/events', {
  headers: { Authorization: `Bearer ${API_KEY}` },
});
After (Grantex):
// New: user-consented, scoped, audited
const { grantToken } = await grantex.tokens.exchange({
  code: authorizationCode,
  agentId: agent.agentDid,
});

const response = await fetch('/api/events', {
  headers: { Authorization: `Bearer ${grantToken}` },
});
4

Add token verification to your API

Use the Express middleware or verify manually:
import { createGrantexMiddleware } from '@grantex/express';

app.use(createGrantexMiddleware({
  baseUrl: 'https://your-auth-service.com',
  apiKey: process.env.GRANTEX_API_KEY,
  requiredScopes: ['calendar:read'],
}));
5

Enable audit logging

Log actions automatically through the SDK:
await grantex.audit.log({
  grantId,
  action: 'calendar.event.created',
  resource: `event:${eventId}`,
});

Migrating from Raw OAuth 2.0

If you already use OAuth 2.0 for agent authorization, Grantex extends the model with agent-aware grants, delegation, and built-in audit.

What stays the same

  • Your identity provider (Okta, Auth0, Google) — keep using it for user login
  • Your users and their accounts
  • The general authorize → consent → token flow pattern

What changes

  • Token format: Opaque access tokens become Grantex JWTs with agent, principal, and scope claims
  • Delegation: OAuth has no standard sub-delegation — Grantex tracks the full chain
  • Audit: No more bolting on audit logging — it’s built into the protocol
  • Revocation: Grant-level revocation cascades to all tokens (not just individual token revocation)

Step-by-step

1

Keep your OAuth login flow

Continue using OIDC for user authentication. Map the authenticated user to a Grantex principalId.
2

Replace OAuth token issuance with Grantex authorization

Before (OAuth):
GET /oauth/authorize?client_id=...&scope=read+write&redirect_uri=...
POST /oauth/token  (authorization_code grant)
After (Grantex):
const { consentUrl } = await grantex.authorize({
  agentId: agent.agentDid,
  userId: user.id,
  scopes: ['calendar:read', 'calendar:write'],
  callbackUrl: 'https://app.com/callback',
});
// Redirect user to consentUrl
// On callback, exchange the code:
const { grantToken } = await grantex.tokens.exchange({
  code, agentId: agent.agentDid,
});
3

Replace token introspection with offline verification

Before (OAuth introspection):
POST /oauth/introspect  { token: "..." }
After (Grantex offline verification):
import { verifyGrantToken } from '@grantex/sdk';

const result = await verifyGrantToken(token, {
  jwksUrl: 'https://your-auth-service.com/.well-known/jwks.json',
});
// No network call needed — JWT verified locally with JWKS
4

Add delegation support (optional)

If your agents delegate to sub-agents:
const delegated = await grantex.grants.delegate({
  grantId: parentGrant.grantId,
  agentId: subAgent.agentDid,
  scopes: ['calendar:read'], // subset of parent scopes
});
5

Enable the permissions dashboard

Give users self-service grant management:
const { dashboardUrl } = await grantex.principalSessions.create({
  principalId: user.id,
});
// Redirect user to dashboardUrl

Further Reading