Authentication

For Coding Agents

authentication.md

Authentication

AGNT uses certificate-based JWT authentication with RSA RS256 signing. You generate certificates through the API, sign JWTs with your private key, and include the token in every request.

There are no API keys. No OAuth flows. No session cookies. Just signed JWTs.

Two API Types

Management APIs operate at the organization level. Creating certificates, configuring providers, managing prompts — anything that doesn't need a user context.

Delegated APIs act on behalf of a specific user. Chats, tasks, memories — anything tied to an end user. These require an email claim in the JWT payload.

The distinction matters because it determines what goes in your JWT.

JWT Structure

Every JWT must include these header fields:

json
{
  "alg": "RS256",
  "kid": "your-certificate-key-id"
}

alg is always RS256. kid is the key ID returned when you create a certificate. AGNT uses the kid to look up the public key and verify your signature.

Management API Payload

json
{
  "iat": 1700000000,
  "exp": 1700003600
}

That's it. No user context needed.

Delegated API Payload

json
{
  "email": "user@example.com",
  "firstName": "Jane",
  "lastName": "Doe",
  "iat": 1700000000,
  "exp": 1700003600
}
FieldRequiredDescription
emailYesEnd user's email address
firstNameNoEnd user's first name
lastNameNoEnd user's last name
iatYesIssued-at timestamp (epoch seconds)
expYesExpiration timestamp (epoch seconds)

Keep token lifetimes short. An hour is plenty. Generate a new token per request if you want — the signing is local and fast.

Signing JWTs

Use the jose library (or any RS256-capable JWT library). Here's JavaScript:

javascript
import { SignJWT, importPKCS8 } from "jose";
import fs from "fs";

const privateKeyPem = fs.readFileSync("./private-key.pem", "utf-8");
const privateKey = await importPKCS8(privateKeyPem, "RS256");

// Management API token (no user context)
const managementToken = await new SignJWT({})
  .setProtectedHeader({ alg: "RS256", kid: "your-certificate-key-id" })
  .setIssuedAt()
  .setExpirationTime("1h")
  .sign(privateKey);

// Delegated API token (with user context)
const delegatedToken = await new SignJWT({
  email: "user@example.com",
  firstName: "Jane",
  lastName: "Doe",
})
  .setProtectedHeader({ alg: "RS256", kid: "your-certificate-key-id" })
  .setIssuedAt()
  .setExpirationTime("1h")
  .sign(privateKey);

Include the token in the Authorization header:

Authorization: Bearer <token>

Auto-Provisioning

When you make a Delegated API call with an email that AGNT hasn't seen before, the user is automatically created. The firstName and lastName claims are used to populate the user record.

No separate user creation step. No signup flow to build. Include the email, and the user exists.

Subsequent calls with the same email update firstName and lastName if the claims are present and different.

Certificate Management

Certificates are how AGNT verifies your JWTs. You create a certificate, AGNT stores the public key, and you keep the private key. Standard RSA key pair stuff.

Create a Certificate

POST https://api.agnt.ai/certificates

Returns an RSA key pair. Save the private key immediately — AGNT does not store it and cannot recover it.

Response includes id, kid, publicKey, and privateKey.

List Certificates

GET https://api.agnt.ai/certificates

Returns all certificates for your organization.

Get Active Certificate

GET https://api.agnt.ai/certificates/active

Returns the currently active certificate.

Get Public Key (No Auth Required)

GET https://api.agnt.ai/certificates/public/:kid

This endpoint is public. No authentication needed. Useful for external services that need to verify tokens you've issued.

Revoke a Certificate

POST https://api.agnt.ai/certificates/:id/revoke

Revoked certificates can no longer be used to verify JWTs. Existing tokens signed with a revoked certificate will be rejected.

Delete a Certificate

DELETE https://api.agnt.ai/certificates/:id

Permanently removes the certificate. This is irreversible.

Super Admin Access

Users with an @agnt.ai email domain are automatically granted super admin access across the platform. This is hardcoded and not configurable — it's an internal operational concern, not a feature.