Adds the full bedroom-developer-docs OpenSpec change implementation: - docs/developers/README.md — index page - docs/developers/quick-start.md — bootstrap to working token in 7 steps - docs/developers/concepts.md — AgentIdP, AGNTCY, lifecycle, OAuth 2.0, free tier - docs/developers/guides/README.md — guide index - docs/developers/guides/register-an-agent.md — all fields, validation, common errors - docs/developers/guides/manage-credentials.md — generate, list, rotate, revoke - docs/developers/guides/issue-and-revoke-tokens.md — OAuth 2.0 flow, introspect, revoke - docs/developers/guides/query-audit-logs.md — filters, pagination, 90-day retention - docs/developers/api-reference.md — all 14 endpoints, all error codes, curl examples Also commits deferred OpenSpec housekeeping from previous session: - Archives phase-1-mvp-implementation change to openspec/changes/archive/ - Adds bedroom-developer-docs change artifacts (30/30 tasks complete) - Syncs 4 delta specs to openspec/specs/ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
129 lines
6.2 KiB
Markdown
129 lines
6.2 KiB
Markdown
# Core Concepts
|
|
|
|
Everything you need to understand how SentryAgent.ai AgentIdP works — without needing to read an RFC.
|
|
|
|
---
|
|
|
|
## What is AgentIdP?
|
|
|
|
SentryAgent.ai AgentIdP is a free, open-source Identity Provider (IdP) built specifically for AI agents. It answers three questions that today's auth systems don't handle for agents:
|
|
|
|
1. **Who is this agent?** — a unique, immutable identity registered in the AgentIdP registry
|
|
2. **Is it who it claims to be?** — verified via OAuth 2.0 credentials
|
|
3. **Is it allowed to do this?** — enforced via scope-based access control
|
|
|
|
Think of it as the difference between a human logging in with a password and a service account authenticating with client credentials. Humans use passwords and MFA. Agents use `client_id` + `client_secret` — and AgentIdP manages that for them.
|
|
|
|
---
|
|
|
|
## What is an AI Agent Identity?
|
|
|
|
A human identity has a username, a password, and a profile. An AI agent identity has the equivalent:
|
|
|
|
| Human | AI Agent |
|
|
|-------|----------|
|
|
| Username | `email` (unique identifier, e.g. `screener-001@myproject.ai`) |
|
|
| Immutable ID | `agentId` (UUID, assigned at registration, never changes) |
|
|
| Profile | `agentType`, `version`, `capabilities`, `owner`, `deploymentEnv` |
|
|
| Password | `clientSecret` (generated, stored as bcrypt hash) |
|
|
| Login session | JWT access token (1 hour, RS256 signed) |
|
|
| Account status | `status` (active / suspended / decommissioned) |
|
|
|
|
The key difference from human identities: an agent's `agentId` is **immutable**. Once assigned, it never changes — even if other metadata is updated. This makes it safe to use as a stable reference across systems.
|
|
|
|
Agents also carry **capabilities** — a list of `resource:action` strings (e.g. `resume:read`, `email:send`) that describe what the agent is permitted to do. These are informational in Phase 1 and will be enforced in the authorization layer in Phase 2.
|
|
|
|
---
|
|
|
|
## AGNTCY Alignment
|
|
|
|
AGNTCY is an open standard from the Linux Foundation that defines how AI agents should be identified, authenticated, and governed across different systems and platforms.
|
|
|
|
The key principle: **agents are first-class identities**, not service accounts bolted onto human auth systems.
|
|
|
|
What this means for you as a developer:
|
|
|
|
- Your agent gets its own permanent ID that travels with it across systems
|
|
- Other AGNTCY-compliant systems can verify your agent's identity without trusting your word
|
|
- Your agent's full lifecycle — registration, credential rotation, decommission — follows a defined, interoperable model
|
|
|
|
SentryAgent.ai implements AGNTCY's non-human identity model. When you register an agent here, you're registering it in a way that aligns with where the industry is heading, not a proprietary silo.
|
|
|
|
---
|
|
|
|
## Agent Lifecycle
|
|
|
|
Every agent moves through a defined set of states. Understanding these states matters because they affect whether your agent can authenticate.
|
|
|
|
### States
|
|
|
|
| State | What it means | Can get tokens? | Can be updated? |
|
|
|-------|---------------|-----------------|-----------------|
|
|
| `active` | Agent is operational | Yes | Yes |
|
|
| `suspended` | Temporarily disabled | No — credentials rejected | Yes — can be reactivated |
|
|
| `decommissioned` | Permanently retired | No — credentials revoked | No |
|
|
|
|
### Transitions
|
|
|
|
```
|
|
registration
|
|
|
|
|
v
|
|
[active] <-----> [suspended]
|
|
|
|
|
v (irreversible)
|
|
[decommissioned]
|
|
```
|
|
|
|
**Suspending** an agent prevents it from obtaining new tokens. Existing unexpired tokens continue to work until they expire. Use suspension when you need to temporarily disable an agent (e.g. investigation, maintenance).
|
|
|
|
**Decommissioning** an agent permanently retires it. All active credentials are immediately revoked. The agent record is retained in the database for audit purposes but the agent can never be reactivated. This operation is **irreversible** — use it only when you intend to permanently retire the agent.
|
|
|
|
---
|
|
|
|
## OAuth 2.0 Client Credentials
|
|
|
|
OAuth 2.0 is the auth standard used everywhere — GitHub, Google, Stripe. AgentIdP uses one specific flow from OAuth 2.0: the **Client Credentials grant**.
|
|
|
|
Here is what actually happens when your agent authenticates:
|
|
|
|
1. Your agent has a `client_id` (its `agentId`) and a `client_secret` (generated by AgentIdP)
|
|
2. Your agent sends both to `POST /token` along with the scopes it needs
|
|
3. AgentIdP verifies the secret, checks the agent is active, and issues a **JWT access token**
|
|
4. Your agent attaches that token as `Authorization: Bearer <token>` on all subsequent API calls
|
|
5. The token expires after 1 hour — your agent requests a new one
|
|
|
|
There are no redirects, no browser windows, no user consent screens. It is a direct machine-to-machine exchange — exactly right for agents that run unattended.
|
|
|
|
### Scopes
|
|
|
|
Scopes limit what a token is permitted to do. Request only the scopes your agent actually needs.
|
|
|
|
| Scope | What it allows |
|
|
|-------|----------------|
|
|
| `agents:read` | Read agent identity records |
|
|
| `agents:write` | Create, update, and decommission agent records |
|
|
| `tokens:read` | Introspect tokens (check if active/expired) |
|
|
| `audit:read` | Query the audit log |
|
|
|
|
Example: an agent that only reads audit logs should request only `audit:read`. If it doesn't have `agents:write`, it cannot accidentally modify agent records.
|
|
|
|
### The secret is shown once
|
|
|
|
When you generate credentials (`POST /agents/{agentId}/credentials`), the `clientSecret` is returned in the response **one time only**. AgentIdP stores a bcrypt hash — the plaintext is gone. If you lose the secret, you rotate the credential to get a new one.
|
|
|
|
---
|
|
|
|
## Free Tier Limits
|
|
|
|
AgentIdP is free. These are the limits on the free tier:
|
|
|
|
| Resource | Limit | What happens when exceeded |
|
|
|----------|-------|---------------------------|
|
|
| Registered agents | 100 | `POST /agents` returns `403 FREE_TIER_LIMIT_EXCEEDED` |
|
|
| Token requests/month | 10,000 | `POST /token` returns `403 unauthorized_client` |
|
|
| API rate limit | 100 req/min | All endpoints return `429 RATE_LIMIT_EXCEEDED` with `X-RateLimit-*` headers |
|
|
| Audit log retention | 90 days | Events older than 90 days are automatically purged; queries return empty results |
|
|
|
|
The monthly token counter resets on the first day of each calendar month. The rate limit window resets every 60 seconds; the reset timestamp is in the `X-RateLimit-Reset` response header.
|