Sample code and applications you can build on Ekam — copy, adapt, ship. No login required.
The piece a gateway imports: validate an agent/human token offline against the JWKS, with an optional live kill-switch.
From an owner key to a short-lived, audience-bound, delegated token in three calls.
Make a governed Ekam token — not a self-signed key — the identity on a signature-based wire protocol (a Nostr/Buzz relay, an mTLS service). Bind the agent to its public key; every minted token then carries an RFC 7800 cnf claim. The relay accepts a message iff the Ekam token verifies + isn't revoked AND the message's signing key == token.cnf. Revocable and rotatable — a self-signed key is neither.
Make Ekam the authorization server for your MCP tools. Your MCP server advertises Ekam (PRM); the MCP client self-registers (RFC 7591) and runs the auth-code + PKCE flow to get a token bound to your server.
Carry a verified identity from app A to app B without re-authenticating — tenant + entity preserved.
Exchange a signed-in human's token + an agent for an attenuated agent token that acts on the user's behalf. The act chain records agent → owner → human, so the resource attributes the call to the person who authorized it.
Let employees sign in with their Ola Google account and receive a type:human Ekam token.
Sign a human into a CLI or agent with no local browser and no client secret. The tool shows a short code; the operator approves it on any other screen at /device; the tool polls and receives a type:human Ekam token.
Cut off an agent instantly; every gateway calling introspection sees it within seconds.
Grant scope beyond an agent's blueprint for a single task: request → approve → a single-use, auto-expiring elevated token.
Pause a high-risk agent action for a human. The agent asks (backchannel), a named person approves out-of-band, and the broker mints a single-use token carrying an approval claim your gateway can enforce. Try it: npm run demo:ciba.
Subscribe your gateway to pushed security events — on revoke, Ekam POSTs a signed session-revoked SET so you evict tokens immediately, no polling.
HR/IdP pushes an identity over SCIM 2.0 → Ekam maps attributes to claims → a signed webhook pre-provisions connector grants. Zero-click.
Resolve one human across all their accounts/entities, then honour a subject-access (export) or right-to-erasure request on the whole Person.
Sign people in with your tenant's own identity provider — any OIDC (Okta/Entra/Auth0), a SAML 2.0 IdP (ADFS/OneLogin/Shibboleth), or GitHub. Registering the IdP binds its identities to your tenant.
Inventory your service accounts / API keys / PATs — by connector or manual ingest — and let Ekam score each for the standing-credential risks (ownerless, stale, never-rotated, over-privileged). Then assign an owner to clear the flag.
Bind an agent token to the workload it runs as. Register the trusted issuer, present a signed workload credential at /oauth/token, and (optionally) require it on the blueprint. The verified workload becomes the token's att claim; a stale proof is rejected.
Findings are auto-created (never POSTed) for every medium|high identity the NHI / shadow / posture scans flag. List the open queue, then acknowledge, remediate, resolve, or risk-accept — through a validated state machine that auto-reopens on re-detection.
Discover agent runtimes Ekam did NOT mint (a claimed ekam_agent_id counts as governed only if it resolves), score Ekam's own agents for governance gaps, and cascade-revoke every agent when its owner is offboarded.
Opt a protected resource into fail-closed ID-JAG issuance: once registered, ONLY a client with an explicit access grant (for the requested scope + the subject's entity) can mint an ID-JAG for it. Unregistered audiences stay open — this is additive, opt-in enterprise governance on top of the RFC 9728 MCP on-ramp.
Ekam holds a 3rd-party provider secret SEALED (Vault-Transit/HSM) and hands a granted, attested agent only a short-lived downstream token — the standing secret never leaves Ekam. The enterprise keeps the secret; the agent gets ephemeral scoped access (the Aembit 'blended identity' pattern).
The complement to egress: an agent acts as a specific HUMAN on a 3rd-party SaaS ('read MY Gmail as me'). An admin registers a provider + grants a blueprint; the human consents once; then a granted agent — holding its own Ekam token whose OBO act-chain names that human — brokers only the user's short-lived downstream token. The refresh token never leaves Ekam. Auth0 'Token Vault' / Descope 'Outbound Apps' pattern.
Periodically re-attest what your agents can do. An NHI campaign snapshots the fine-grained agent grant edges — A2A call edges, MCP-EMA resource grants, egress grants — plus the agent principals; a reviewer approves (keep) or denies (revoke) each; on close, every denied edge is DELETED. The IGA/SOX evidence auditors demand for non-human identities, with the same engine that certifies human access.
Governed agent-to-agent call tokens. Register a callee as callable, grant a caller blueprint an edge to it, then mint a call token: aud=callee, sub stays the caller, the caller's owner→human attribution is preserved, scope is attenuated to caller∩grant, and it's deny-by-default + revocable. This is the authorization layer a message/transport plane (Google A2A, MCP, ACP, the Vahini/Buzz relay) doesn't provide itself.
Client-ID Metadata Documents (the DCR replacement, MCP 2026-07): a spec-current MCP client presents an https URL as its client_id and Ekam resolves it on the fly at /authorize — no registration step. Fail-closed and anti-spoof (the document's own client_id must equal its URL).
The piece a gateway imports: validate an agent/human token offline against the JWKS, with an optional live kill-switch.
import { createEkamVerifier } from "@krutrim/ekam-verify";
const verify = createEkamVerifier({
issuer: "https://ekam.olakrutrim.com",
jwksUri: "https://ekam.olakrutrim.com/.well-known/jwks.json",
audience: "https://your-gateway.example",
introspectUrl: "https://ekam.olakrutrim.com/oauth/introspect", // optional live revocation
});
app.use(async (req, res, next) => {
try {
const p = await verify(req.headers.authorization?.split(" ")[1]);
req.principal = p; // { agentId, ownerId, scopes, tenant, entity, budgetRef }
if (!p.scopes.includes("models:invoke")) return res.status(403).end();
next();
} catch { res.status(401).end(); }
});From an owner key to a short-lived, audience-bound, delegated token in three calls.
BASE=https://ekam.olakrutrim.com
BP=$(curl -s $BASE/v1/blueprints -H "authorization: Bearer $OWNER_KEY" -H 'content-type: application/json' \
-d '{"name":"support","scopes":["models:invoke"],"allowedAudiences":["https://your-gateway.example"],"tokenTtlSeconds":900}' | jq -r .id)
AG=$(curl -s $BASE/v1/agents -H "authorization: Bearer $OWNER_KEY" -H 'content-type: application/json' \
-d "{\"blueprintId\":\"$BP\",\"name\":\"support-bot\"}" | jq -r .id)
curl -s $BASE/oauth/token -H "authorization: Bearer $OWNER_KEY" -H 'content-type: application/json' \
-d "{\"grant_type\":\"urn:ietf:params:oauth:grant-type:token-exchange\",\"agent_id\":\"$AG\",\"resource\":\"https://your-gateway.example\",\"scope\":\"models:invoke\"}"Make a governed Ekam token — not a self-signed key — the identity on a signature-based wire protocol (a Nostr/Buzz relay, an mTLS service). Bind the agent to its public key; every minted token then carries an RFC 7800 cnf claim. The relay accepts a message iff the Ekam token verifies + isn't revoked AND the message's signing key == token.cnf. Revocable and rotatable — a self-signed key is neither.
BASE=https://ekam.olakrutrim.com
# 1) Provision the agent BOUND to its wire public key (Nostr x-only secp256k1, 64 hex). Owner-authenticated.
AG=$(curl -s $BASE/v1/agents -H "authorization: Bearer $OWNER_KEY" -H 'content-type: application/json' \
-d '{"name":"relay-agent","blueprintId":"'$BP'","nostr_pubkey":"e2c9…64hex…d7e"}' | jq -r .id)
# (rotate later: PUT $BASE/v1/agents/$AG/cnf {"nostr_pubkey":"<new hex>"} ; clear with null)
# 2) Broker a short-lived token — it carries the binding.
curl -s $BASE/oauth/token -H "authorization: Bearer $OWNER_KEY" -H 'content-type: application/json' \
-d '{"grant_type":"urn:ietf:params:oauth:grant-type:token-exchange","agent_id":"'$AG'","resource":"https://relay.example","scope":"relay:connect"}'
# -> access_token whose payload has: "cnf": { "nostr_pub": "e2c9…d7e" }
# 3) The relay (offline) enforces the B1 seam — pseudocode:
# payload = jwtVerify(token, JWKS_of(https://ekam.olakrutrim.com), { issuer, audience: "https://relay.example" })
# accept = introspect(token).active && message.pubkey == payload.cnf.nostr_pub
# kill-switch: POST $BASE/v1/agents/$AG/revoke -> the token introspects active:false, relay drops the peer.
# cnf is protocol-neutral: pass a raw {"cnf": {...}} for a DPoP jkt / mTLS x5t#S256 instead of nostr_pubkey.Make Ekam the authorization server for your MCP tools. Your MCP server advertises Ekam (PRM); the MCP client self-registers (RFC 7591) and runs the auth-code + PKCE flow to get a token bound to your server.
# 1) Your MCP server advertises Ekam as its AS (RFC 9728):
# GET https://mcp.example.com/.well-known/oauth-protected-resource
# { "resource":"https://mcp.example.com", "authorization_servers":["https://ekam.olakrutrim.com"] }
# 2) The MCP client discovers Ekam + self-registers (public client, PKCE — no secret)
curl -s https://ekam.olakrutrim.com/register -H 'content-type: application/json' \
-d '{"client_name":"my-mcp-client","redirect_uris":["http://127.0.0.1:7777/callback"]}'
# -> { "client_id":"clt_…", "token_endpoint_auth_method":"none" }
# 3) Send the signed-in user to /authorize with a PKCE challenge (S256). Ekam 302s back
# to redirect_uri?code=… (the user authenticates with their Ekam SSO session):
# GET https://ekam.olakrutrim.com/authorize?response_type=code&client_id=clt_…&redirect_uri=…
# &code_challenge=<base64url(sha256(verifier))>&code_challenge_method=S256
# &resource=https://mcp.example.com&scope=mcp:use&state=…
# 4) Redeem the code + the PKCE verifier for a token bound to your MCP server:
curl -s https://ekam.olakrutrim.com/oauth/token -H 'content-type: application/json' -d '{
"grant_type":"authorization_code","code":"ac_…","code_verifier":"<verifier>",
"client_id":"clt_…","redirect_uri":"http://127.0.0.1:7777/callback"}'
# -> { "access_token":"<jwt aud=https://mcp.example.com>", ... }
# Your MCP server verifies it OFFLINE against the JWKS (single-use code, PKCE-bound).Carry a verified identity from app A to app B without re-authenticating — tenant + entity preserved.
# App A issues an ID-JAG (token-exchange)
curl -s https://ekam.olakrutrim.com/oauth/token -H 'content-type: application/json' -d '{
"grant_type":"urn:ietf:params:oauth:grant-type:token-exchange",
"requested_token_type":"urn:ietf:params:oauth:token-type:id-jag",
"subject_token":"<app-A token>", "audience":"https://app-b.example" }'
# App B redeems it (jwt-bearer) for a local access token
curl -s https://ekam.olakrutrim.com/oauth/token -H 'content-type: application/json' -d '{
"grant_type":"urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion":"<id-jag>" }'Exchange a signed-in human's token + an agent for an attenuated agent token that acts on the user's behalf. The act chain records agent → owner → human, so the resource attributes the call to the person who authorized it.
# A human signs in (SSO) and holds a type:human Ekam token. The owner exchanges it for an
# agent token that acts ON BEHALF OF that human — normal blueprint attenuation still applies.
curl -s https://ekam.olakrutrim.com/oauth/token -H "authorization: Bearer $OWNER_KEY" -H 'content-type: application/json' -d '{
"grant_type":"urn:ietf:params:oauth:grant-type:token-exchange",
"subject_token":"<the human'\''s Ekam token>",
"subject_token_type":"urn:ietf:params:oauth:token-type:access_token",
"agent_id":"agt_123", "resource":"https://your-gateway.example", "scope":"models:invoke" }'
# -> an agent token whose claims carry the delegation chain:
# sub = agt_123 (the agent acting)
# act = { sub: own_…, (the owner the agent belongs to)
# act: { sub: hum_… } } (the human who delegated — OBO)
# With @krutrim/ekam-verify the gateway reads p.onBehalfOf to attribute the call to the user.Let employees sign in with their Ola Google account and receive a type:human Ekam token.
<a href="https://ekam.olakrutrim.com/auth/login">Sign in with Google</a>
<!-- On return, /auth/callback hands back #access_token=<jwt>&email=<email>.
Decode it for { sub, type:'human', tenant, entity, scope }. Non-Ola domains
are routed to Request access automatically. -->Sign a human into a CLI or agent with no local browser and no client secret. The tool shows a short code; the operator approves it on any other screen at /device; the tool polls and receives a type:human Ekam token.
BASE=https://ekam.olakrutrim.com
# 1) The device (public client — no secret) starts the flow. Gets a device_code to poll with and a
# short user_code the human types on a second screen.
INIT=$(curl -s $BASE/device_authorization -H 'content-type: application/json' \
-d '{"client_id":"my-cli","scope":"openid email"}')
DEVICE_CODE=$(echo "$INIT" | jq -r .device_code)
echo "$INIT" | jq -r '"Go to \(.verification_uri) and enter \(.user_code)"'
# -> Go to https://ekam.olakrutrim.com/device and enter K7QF-2M9X
# (or just open .verification_uri_complete — it prefills the code)
# 2) The human opens /device on ANY browser, signs in with Ekam SSO, and approves the code.
# 3) Meanwhile the device POLLS the token endpoint (device_code grant). While waiting it returns
# {"error":"authorization_pending"} or {"error":"slow_down"} — honour the interval (default 5s).
while :; do
RES=$(curl -s $BASE/oauth/token -H 'content-type: application/json' \
-d "{\"grant_type\":\"urn:ietf:params:oauth:grant-type:device_code\",\"device_code\":\"$DEVICE_CODE\",\"client_id\":\"my-cli\"}")
ERR=$(echo "$RES" | jq -r '.error // empty')
case "$ERR" in
authorization_pending|slow_down) sleep 5 ;;
"") echo "$RES" | jq -r .access_token; break ;; # approved -> single-use human token
*) echo "login failed: $ERR" >&2; break ;; # access_denied / expired_token
esac
done
# The minted token is type:human (the approving person), aud + scope as requested — verify it offline
# against the JWKS just like any other Ekam token.Cut off an agent instantly; every gateway calling introspection sees it within seconds.
# Revoke
curl -s -X POST https://ekam.olakrutrim.com/v1/agents/agt_123/revoke -H "authorization: Bearer $OWNER_KEY"
# Any token it holds now introspects inactive
curl -s https://ekam.olakrutrim.com/oauth/introspect -H 'content-type: application/json' -d '{"token":"<jwt>"}'
# -> { "active": false }Grant scope beyond an agent's blueprint for a single task: request → approve → a single-use, auto-expiring elevated token.
BASE=https://ekam.olakrutrim.com
# 1) request elevation — scope BEYOND the blueprint, for one task
ELR=$(curl -s $BASE/v1/elevation-requests -H "authorization: Bearer $OWNER_KEY" -H 'content-type: application/json' \
-d '{"agentId":"agt_123","resource":"https://your-gateway.example","scopes":["admin:write"],"reason":"rotate prod secret","ttlSeconds":300}' | jq -r .id)
# 2) an approver decides (admin OR a workspace admin — separation of duties)
curl -s -X POST $BASE/v1/elevation-requests/$ELR/approve -H "authorization: Bearer $ADMIN_TOKEN"
# 3) redeem ONCE at the broker -> a single-use, short-TTL token that auto-expires
curl -s $BASE/oauth/token -H "authorization: Bearer $OWNER_KEY" -H 'content-type: application/json' \
-d "{\"grant_type\":\"urn:ietf:params:oauth:grant-type:token-exchange\",\"agent_id\":\"agt_123\",\"resource\":\"https://your-gateway.example\",\"elevation_id\":\"$ELR\"}"Pause a high-risk agent action for a human. The agent asks (backchannel), a named person approves out-of-band, and the broker mints a single-use token carrying an approval claim your gateway can enforce. Try it: npm run demo:ciba.
BASE=https://ekam.olakrutrim.com
# 1) the agent asks a NAMED human to consent to a specific in-scope-but-sensitive action
REQ=$(curl -s $BASE/bc-authorize -H "authorization: Bearer $OWNER_KEY" -H 'content-type: application/json' -d '{
"agentId":"agt_123","resource":"https://pay.example","scope":"payments:write",
"action":"Refund ₹50,000 to order #1002","loginHint":"priya.finance@olacabs.com",
"bindingMessage":"ACME-4417"}')
ARID=$(echo "$REQ" | jq -r .auth_req_id)
# 2) the client POLLS the token endpoint (OpenID CIBA poll mode) until the human decides
# -> {"error":"authorization_pending"} / {"error":"slow_down"} while waiting
curl -s $BASE/oauth/token -H "authorization: Bearer $OWNER_KEY" -H 'content-type: application/json' \
-d "{\"grant_type\":\"urn:openid:params:grant-type:ciba\",\"auth_req_id\":\"$ARID\"}"
# 3) the named human approves out-of-band (their own session — SoD: the owner key can't self-approve)
curl -s -X POST $BASE/v1/ciba-requests/$ARID/approve -H "authorization: Bearer $HUMAN_TOKEN"
# 4) the next poll returns a SINGLE-USE, action-bound token carrying the approval claim:
# approval: { request_id, action, approved_by }
# Your gateway gates high-risk ops on it — with @krutrim/ekam-verify:
# const p = await verify(token);
# if (amount >= 10000 && !p.approval) return res.status(403).end(); // needs a humanSubscribe your gateway to pushed security events — on revoke, Ekam POSTs a signed session-revoked SET so you evict tokens immediately, no polling.
BASE=https://ekam.olakrutrim.com
# register a push receiver (defaults to the session-revoked event)
curl -s $BASE/ssf/streams -H "authorization: Bearer $OWNER_KEY" -H 'content-type: application/json' \
-d '{"endpoint_url":"https://your-gateway.example/secevents"}'
# test connectivity — pushes a signed verification SET to your endpoint
curl -s -X POST $BASE/ssf/streams/ssf_123/verify -H "authorization: Bearer $OWNER_KEY"
# your receiver verifies the SET against the JWKS, then drops the agent's sessions:
# const jwks = createRemoteJWKSet(new URL("https://ekam.olakrutrim.com/.well-known/jwks.json"));
# const { payload } = await jwtVerify(setJwt, jwks, { issuer: "https://ekam.olakrutrim.com" });
# payload.events["https://schemas.openid.net/secevent/caep/event-type/session-revoked"].subject.idHR/IdP pushes an identity over SCIM 2.0 → Ekam maps attributes to claims → a signed webhook pre-provisions connector grants. Zero-click.
BASE=https://ekam.olakrutrim.com
# 1) HR/IdP pushes a new joiner (SCIM 2.0, service-token auth)
curl -s $BASE/scim/v2/Users -H "authorization: Bearer $SCIM_TOKEN" -H 'content-type: application/json' -d '{
"schemas":["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:ola:2.0:User"],
"userName":"ankit@olaelectric.com","displayName":"Ankit Sharma","active":true,
"urn:ietf:params:scim:schemas:extension:ola:2.0:User":{"jobLevel":"L5","department":"platform-engineering","entity":"ola-electric","costCenter":"platform-eng"}}'
# 2) register your provisioner once (admin) — receives signed identity.provisioned / identity.deactivated
curl -s $BASE/admin/webhooks -H "authorization: Bearer $ADMIN_TOKEN" -H 'content-type: application/json' -d '{
"name":"connector-provisioner","url":"https://your-portal.olakrutrim.com/hooks/ekam",
"events":["identity.provisioned","identity.deactivated"],"secret":"<hmac-shared-secret>"}'
# 3) verify the push on your receiver (HMAC-SHA256 of the raw body), then diff scopes:
# const sig = "sha256=" + crypto.createHmac("sha256", SECRET).update(rawBody).digest("hex");
# if (sig !== req.headers["x-ekam-signature"]) return res.status(401).end();
# payload.identity.scope vs payload.previous_scope -> add/revoke connector grantsResolve one human across all their accounts/entities, then honour a subject-access (export) or right-to-erasure request on the whole Person.
BASE=https://ekam.olakrutrim.com
# 1) resolve the canonical Person from any identifier (employeeId, email, phone, nationalId)
PID=$(curl -s $BASE/v1/persons/resolve -H "authorization: Bearer $ADMIN_TOKEN" -H 'content-type: application/json' \
-d '{"employeeId":"E-12345"}' | jq -r .id)
# 2) DPDP §11 access — export everything Ekam holds (national id returned redacted)
curl -s $BASE/v1/persons/$PID/export -H "authorization: Bearer $ADMIN_TOKEN"
# 3) DPDP §12 erasure — anonymize the Person + cascade (deactivate SCIM, tombstone human auth);
# the SCIM deactivation webhook drives connector-grant revocation downstream
curl -s -X POST $BASE/v1/persons/$PID/erase -H "authorization: Bearer $ADMIN_TOKEN"Sign people in with your tenant's own identity provider — any OIDC (Okta/Entra/Auth0), a SAML 2.0 IdP (ADFS/OneLogin/Shibboleth), or GitHub. Registering the IdP binds its identities to your tenant.
BASE=https://ekam.olakrutrim.com
# --- OIDC ---
# 1) Register your OIDC IdP once (admin). Ekam routes incoming id_tokens by 'iss' and verifies the JWKS.
curl -s $BASE/v1/tenants/<tenant>/idps -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' -d '{
"kind": "oidc", "name": "Acme Okta",
"issuer": "https://acme.okta.com",
"jwksUri": "https://acme.okta.com/oauth2/v1/keys",
"audience": "<your client id>"
}'
# 2) Exchange an id_token from that IdP for a type:human Ekam token (bound to your tenant)
curl -s $BASE/oauth/federate/oidc -H 'content-type: application/json' -d '{
"id_token": "<id_token from your IdP>",
"resource": "https://your-gateway.example",
"scope": "agents:manage"
}'
# --- SAML 2.0 (enterprise IdPs that speak SAML, not OIDC) ---
# Register the IdP with its entityID + signing cert, hand it Ekam's SP metadata
# ($BASE/auth/saml/metadata), and it POSTs its SAMLResponse to $BASE/auth/saml/acs.
curl -s $BASE/v1/tenants/<tenant>/idps -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' -d '{
"kind": "saml", "name": "Acme SSO",
"entityId": "https://idp.acme.com/saml/metadata",
"ssoUrl": "https://idp.acme.com/sso/saml",
"x509cert": "-----BEGIN CERTIFICATE-----\n…\n-----END CERTIFICATE-----"
}'
# GitHub login is a browser flow: send the user to
# $BASE/auth/github/login (set GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET)
# An unregistered issuer/entityID is refused — 403 idp_not_registered (no implicit trust).Inventory your service accounts / API keys / PATs — by connector or manual ingest — and let Ekam score each for the standing-credential risks (ownerless, stale, never-rotated, over-privileged). Then assign an owner to clear the flag.
BASE=https://ekam.olakrutrim.com
# 1) Let a connector fetch a source's ungoverned identities (config incl. token is per-run, NOT persisted).
# Eight connectors: github, m365, okta, gcp, aws, snowflake, slack, datadog.
curl -s -X POST $BASE/v1/tenants/ola/nhi-discovery/connectors/github/run \
-H "authorization: Bearer $ADMIN_TOKEN" -H 'content-type: application/json' \
-d '{"org":"ola-silicon","token":"ghp_…"}'
# -> 201 { "id":"drun_…","source":"github","status":"ok","discovered":18,"upserted":18,"error":null,… }
# (a bad token / missing scope is a 200 { status:"error", discovered:0, error:"…" } — a scan never 500s)
# 2) …or POST an inventory yourself (1..1000 rows). Same inventory + posture path.
curl -s $BASE/v1/tenants/ola/nhi-discovery/ingest -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' -d '{"items":[
{"source":"aws","kind":"iam_user","externalId":"AIDAEXAMPLE","name":"ci-deployer",
"privileges":["AdministratorAccess"],"lastRotatedAt":"2025-01-01T00:00:00Z","status":"active"}]}'
# -> 201 { "ingested":1, "items":[ { "id":"dnhi_…","risk":"high","flags":["over_privileged","no_rotation"] } ] }
# 3) Read the ISPM aggregate + the high-risk rows.
curl -s $BASE/v1/tenants/ola/nhi-discovery/report -H "authorization: Bearer $ADMIN_TOKEN"
# -> { total, byRisk:{low,medium,high}, byFlag:{ownerless,stale,no_rotation,over_privileged,disabled_present}, bySource, byKind }
curl -s "$BASE/v1/tenants/ola/nhi-discovery?risk=high" -H "authorization: Bearer $ADMIN_TOKEN"
# 4) Remediate: assign an owner (clears the ownerless flag, re-scores posture).
curl -s -X PUT $BASE/v1/nhi-discovery/dnhi_123/owner -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' -d '{"ownerRef":"team:platform-eng"}'
# Every medium|high row also auto-opens a finding — work it via the remediation lifecycle (next recipe).Bind an agent token to the workload it runs as. Register the trusted issuer, present a signed workload credential at /oauth/token, and (optionally) require it on the blueprint. The verified workload becomes the token's att claim; a stale proof is rejected.
BASE=https://ekam.olakrutrim.com
# 1) Register the workload-identity fabric you trust (a cluster's OIDC issuer, a cloud OIDC, a SPIFFE domain).
curl -s $BASE/v1/tenants/ola/attestation-issuers -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' -d '{
"issuer":"https://kubernetes.default.svc",
"jwksUri":"https://kubernetes.default.svc/openid/v1/jwks",
"kind":"k8s_sa","label":"prod cluster"}'
# -> 201 { "id":"atti_…","kind":"k8s_sa",… }
# 2) (P3) optionally tighten the freshness window (default 3600s). blueprint.attFreshnessSeconds overrides this.
curl -s -X PUT $BASE/v1/tenants/ola/attestation-policy -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' -d '{"freshnessSeconds":900}'
# 3) (P1) The agent presents workload_attestation at mint — on ANY seam (default broker shown; also OBO /
# delegation / CIBA on /oauth/token, and /nhi/token). Ekam verifies signature + trusted iss + freshness.
curl -s $BASE/oauth/token -H "authorization: Bearer $OWNER_KEY" -H 'content-type: application/json' -d '{
"grant_type":"urn:ietf:params:oauth:grant-type:token-exchange",
"agent_id":"agt_123","resource":"https://your-gateway.example","scope":"models:invoke",
"workload_attestation":"<signed k8s SA / cloud OIDC / SPIFFE JWT>"}'
# -> token whose claims carry:
# "att": { "workload":"k8s:payments/deployer","method":"k8s_sa","issuer":"…","iat":…, "exp":iat+window }
# Failure modes (400): invalid_attestation (untrusted iss/bad sig) | attestation_stale (iat past the window)
# | attestation_required (blueprint has requireAttestation:true and no surviving proof).
# (P2) A blueprint minted with "requireAttestation": true refuses any un-attested mint at every seam.
# Continuous re-attestation is free: agents have no refresh grant, so every TTL they re-hit /oauth/token and
# re-clear the gate — a cached/stale proof is rejected.Findings are auto-created (never POSTed) for every medium|high identity the NHI / shadow / posture scans flag. List the open queue, then acknowledge, remediate, resolve, or risk-accept — through a validated state machine that auto-reopens on re-detection.
BASE=https://ekam.olakrutrim.com
# 1) List the queue. byStatus is over ALL findings (by effective status), independent of the filters.
curl -s "$BASE/v1/tenants/ola/findings?status=open" -H "authorization: Bearer $ADMIN_TOKEN"
# -> { total, byStatus:{open,acknowledged,remediating,resolved,risk_accepted}, items:[{…,effectiveStatus}] }
# filters: status | type=nhi|shadow_agent|agent | risk | surface=open|risk_accepted
# 2) Acknowledge (time-boxed — auto-sets ackExpiresAt = now + 30 days unless you pass one).
curl -s -X PATCH $BASE/v1/findings/fnd_123 -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' -d '{"status":"acknowledged","assignee":"ankit@olacabs.com","note":"rotating the key"}'
# 3) Resolve once fixed — or risk-accept with a MANDATORY reason (empty reason -> 422 reason_required).
curl -s -X PATCH $BASE/v1/findings/fnd_123 -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' -d '{"status":"resolved"}'
curl -s -X PATCH $BASE/v1/findings/fnd_456 -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' -d '{"status":"risk_accepted","reason":"break-glass SA, compensating controls in place"}'
# Illegal move -> 409 illegal_transition. A finding is keyed by a stable fingerprint(source,kind,name), so a
# later scan that re-detects the SAME thing AUTO-REOPENS a resolved/acknowledged finding (reopenedCount++).
# An expired acknowledgement reads as open at the read boundary (effectiveStatus), never persisted.Discover agent runtimes Ekam did NOT mint (a claimed ekam_agent_id counts as governed only if it resolves), score Ekam's own agents for governance gaps, and cascade-revoke every agent when its owner is offboarded.
BASE=https://ekam.olakrutrim.com
# 1) Scan an external agent platform (openai today). Token is per-run, NOT persisted.
curl -s -X POST $BASE/v1/tenants/ola/shadow-agents/scan/openai -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' -d '{"token":"sk-…","org":"org-abc","maxPages":20}'
# -> 201 { "source":"openai","status":"ok","discovered":12,"governed":3,"shadow":9 }
curl -s "$BASE/v1/tenants/ola/shadow-agents?governed=false&risk=high" -H "authorization: Bearer $ADMIN_TOKEN"
# flags: ungoverned (core) | risky_tool (shell/exec/code_interpreter/payment/…) | over_tooled (>8) | stale | disabled_present
# risk = HIGH iff ungoverned OR (risky_tool AND active)
# 2) Score the agents Ekam DID mint for governance gaps (orphaned | over_privileged | stale | never_used | …).
curl -s $BASE/v1/tenants/ola/agents/posture/report -H "authorization: Bearer $ADMIN_TOKEN"
# -> aggregate + orphaned:[{id,name,ownerId}] (risk = HIGH iff orphaned OR over_privileged)
# 3) Offboard an owner: retire + revoke ALL its agents (kill-switch + a CAEP session-revoked push each),
# then record the offboarding so survivors score orphaned. Idempotent.
curl -s -X POST $BASE/v1/owners/own_123/offboard -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' -d '{"by":"hr-offboarding"}'
# -> { "ownerId":"own_123","revokedAgents":4,… }
# reinstate clears the orphaned flag but does NOT un-revoke the agents (re-provision explicitly).Opt a protected resource into fail-closed ID-JAG issuance: once registered, ONLY a client with an explicit access grant (for the requested scope + the subject's entity) can mint an ID-JAG for it. Unregistered audiences stay open — this is additive, opt-in enterprise governance on top of the RFC 9728 MCP on-ramp.
BASE=https://ekam.olakrutrim.com
# 1) Register the MCP server's audience as a governed resource (declare the scopes it supports).
curl -s -X POST $BASE/v1/tenants/ola/mcp-resources -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' \
-d '{"resource":"https://mcp.example.com","name":"Example MCP","scopes_supported":["tools:read","tools:call"]}'
# -> from now on, minting an ID-JAG for https://mcp.example.com is DENIED without a grant.
# 2) Grant a specific client access, for scopes <= the resource's supported set (optionally scoped to entities).
curl -s -X POST $BASE/v1/tenants/ola/mcp-grants -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' \
-d '{"client_id":"cli_abc","resource":"https://mcp.example.com","scopes":["tools:read"]}'
# omit "entities" to allow any entity in the tenant; DELETE …/mcp-grants/:id to revoke.Ekam holds a 3rd-party provider secret SEALED (Vault-Transit/HSM) and hands a granted, attested agent only a short-lived downstream token — the standing secret never leaves Ekam. The enterprise keeps the secret; the agent gets ephemeral scoped access (the Aembit 'blended identity' pattern).
BASE=https://ekam.olakrutrim.com
# 1) Admin registers the downstream connection — the client_secret is sealed on write and never echoed back.
curl -s -X POST $BASE/v1/tenants/ola/egress-connections -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' \
-d '{"name":"snowflake","token_url":"https://acct.snowflakecomputing.com/oauth/token","client_id":"svc","client_secret":"REDACTED","scopes_supported":["session:role:analyst"]}'
# 2) Admin grants an agent BLUEPRINT brokered access (scopes <= the connection's supported set).
curl -s -X POST $BASE/v1/tenants/ola/egress-grants -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' \
-d '{"blueprint_id":"bp_etl","connection":"snowflake","scopes":["session:role:analyst"]}'
# 3) The agent brokers with its OWN Ekam token — gets back ONLY a short-lived downstream token.
curl -s $BASE/v1/egress/token -H "authorization: Bearer $AGENT_TOKEN" \
-H 'content-type: application/json' -d '{"connection":"snowflake","scope":"session:role:analyst"}'
# -> { access_token (downstream), token_type, expires_in, scope, connection }
# the sealed secret is opened just-in-time, used once, never returned. A requireAttestation blueprint
# must also pass "workload_attestation" here (fail-closed, same as at mint).The complement to egress: an agent acts as a specific HUMAN on a 3rd-party SaaS ('read MY Gmail as me'). An admin registers a provider + grants a blueprint; the human consents once; then a granted agent — holding its own Ekam token whose OBO act-chain names that human — brokers only the user's short-lived downstream token. The refresh token never leaves Ekam. Auth0 'Token Vault' / Descope 'Outbound Apps' pattern.
BASE=https://ekam.olakrutrim.com
# 1) Admin registers the 3rd-party OAuth provider (client_secret sealed at rest, never echoed back).
curl -s -X POST $BASE/v1/tenants/ola/connected-account-providers -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' \
-d '{"name":"google","authorization_url":"https://accounts.google.com/o/oauth2/v2/auth","token_url":"https://oauth2.googleapis.com/token","client_id":"…","client_secret":"…","scopes_supported":["gmail.readonly"]}'
# 2) Admin grants an agent BLUEPRINT use of that provider's linked accounts (scopes <= supported).
curl -s -X POST $BASE/v1/tenants/ola/connected-account-grants -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' -d '{"blueprint_id":"bp_assistant","provider":"google","scopes":["gmail.readonly"]}'
# 3) The HUMAN consents once — open this in their browser (authenticated). Google → callback stores sealed tokens.
open "$BASE/v1/connected-accounts/authorize?provider=google" # 302 → Google consent → /callback links the account
# 4) The agent, acting ON BEHALF OF that human (its Ekam token's act-chain names them), brokers HER token.
curl -s $BASE/v1/connected-accounts/token -H "authorization: Bearer $AGENT_OBO_TOKEN" \
-H 'content-type: application/json' -d '{"provider":"google"}'
# -> { access_token (the USER's short-lived Google token), expires_in, scope, provider, on_behalf_of: "hum_…" }
# the agent calls the Gmail API with access_token. Ekam refreshes it transparently; the refresh token never leaves.Periodically re-attest what your agents can do. An NHI campaign snapshots the fine-grained agent grant edges — A2A call edges, MCP-EMA resource grants, egress grants — plus the agent principals; a reviewer approves (keep) or denies (revoke) each; on close, every denied edge is DELETED. The IGA/SOX evidence auditors demand for non-human identities, with the same engine that certifies human access.
BASE=https://ekam.olakrutrim.com
# 1) Open an NHI access-certification campaign — nhi:true snapshots agent + a2a/mcp/egress grant edges.
# defaultAction=approve keeps anything not explicitly denied; reviewer routes items to one human.
CID=$(curl -s -X POST $BASE/v1/tenants/ola/certification-campaigns -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' \
-d '{"name":"Q3 machine-access review","scope":"machine identities","nhi":true,"defaultAction":"approve","dueAt":"2026-09-30T00:00:00Z"}' \
| jq -r .campaign.id)
# 2) Review the snapshot — each item is a certifiable entitlement (subjectKind + human-readable descriptor).
curl -s $BASE/v1/certification-campaigns/$CID/items -H "authorization: Bearer $ADMIN_TOKEN" \
| jq '.items[] | {id, subjectKind, entitlement}'
# e.g. { subjectKind:"a2a_grant", entitlement:"a2a:caller-bp→callee-agent:[models:read]" }
# 3) Deny a stale A2A edge (revoke); approve the rest by leaving them (defaultAction=approve keeps them).
curl -s -X POST $BASE/v1/certification-items/$ITEM_ID/deny -H "authorization: Bearer $ADMIN_TOKEN"
# 4) Close — every DENIED edge is deleted; kept edges survive. (A dueAt sweep auto-closes overdue campaigns.)
curl -s -X POST $BASE/v1/certification-campaigns/$CID/close -H "authorization: Bearer $ADMIN_TOKEN"
# -> { campaign, items, removedGrants } the revoked grant edges are now gone from the tenant.Governed agent-to-agent call tokens. Register a callee as callable, grant a caller blueprint an edge to it, then mint a call token: aud=callee, sub stays the caller, the caller's owner→human attribution is preserved, scope is attenuated to caller∩grant, and it's deny-by-default + revocable. This is the authorization layer a message/transport plane (Google A2A, MCP, ACP, the Vahini/Buzz relay) doesn't provide itself.
BASE=https://ekam.olakrutrim.com
# 0) By default an A2A call is DENIED — the callee isn't registered callable and there's no grant.
# 1) Register the callee agent as A2A-callable (tenant admin), declaring the scopes it supports.
curl -s -X POST $BASE/v1/tenants/ola/a2a-callees -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' \
-d '{"agent_id":"agt_callee","audience":"https://callee.svc","scopes_supported":["models:read"]}'
# 2) Grant a CALLER BLUEPRINT the right to call that callee, for a scope <= the callee's supported set.
curl -s -X POST $BASE/v1/tenants/ola/a2a-grants -H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' \
-d '{"caller_blueprint_id":"bp_caller","callee_agent_id":"agt_callee","scopes":["models:read"]}'
# 3) The caller agent (holding its OWN Ekam token in $CALLER_TOKEN) mints a call token for the callee.
curl -s $BASE/oauth/token -H 'content-type: application/json' \
-d "{\"grant_type\":\"urn:ietf:params:oauth:grant-type:token-exchange\",\"requested_token_type\":\"urn:ekam:token-type:a2a\",\"subject_token\":\"$CALLER_TOKEN\",\"a2a_target\":\"agt_callee\",\"scope\":\"models:read\"}"
# -> { access_token } with: aud=https://callee.svc · sub=<caller agent> · a2a.callee=agt_callee
# act chain (agent->owner->human) preserved · scope narrowed to the grant · delegation depth +1 (capped)
# The callee verifies it like any Ekam token (signature + iss + its own aud) and reads who is really calling.
# Kill-switch: DELETE the grant (…/a2a-grants/:id) to cut that caller->callee edge instantly.Client-ID Metadata Documents (the DCR replacement, MCP 2026-07): a spec-current MCP client presents an https URL as its client_id and Ekam resolves it on the fly at /authorize — no registration step. Fail-closed and anti-spoof (the document's own client_id must equal its URL).
BASE=https://ekam.olakrutrim.com
# Ekam advertises support in discovery:
curl -s $BASE/.well-known/openid-configuration | jq .client_id_metadata_document_supported # -> true
# Host a client metadata document at a stable https URL. Its "client_id" MUST equal its own URL.
# https://app.example.com/oauth-client.json :
# { "client_id":"https://app.example.com/oauth-client.json",
# "client_name":"Example MCP App",
# "redirect_uris":["https://app.example.com/callback"] }
# Then just use that URL as client_id at /authorize — no /register call needed:
open "$BASE/authorize?response_type=code&client_id=https%3A%2F%2Fapp.example.com%2Foauth-client.json\
&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&code_challenge=$CC&code_challenge_method=S256"
# Ekam fetches + validates the doc (https-only, valid JSON, redirect_uris present, client_id==URL),
# caches the client, and runs the normal PKCE flow. A bad doc -> 400 invalid_client (+ cimd_error).