Files
sentryagent-idp/docs/developers/quick-start.md
SentryAgent.ai Developer f9a6a8aafb docs(devops): update all documentation for DockerSpec compliance
- Replace all docker-compose.yml/docker-compose.monitoring.yml references with
  compose.yaml/compose.monitoring.yaml (modern Compose Spec naming)
- Replace all `docker-compose` CLI commands with `docker compose` (plugin syntax)
- Update Dockerfile stage descriptions: node:18-alpine → node:20.11-bookworm-slim,
  built-in node user → explicit nodeapp:1001 non-root user
- Update image version references: postgres:14-alpine → postgres:14.12-alpine3.19,
  redis:7-alpine → redis:7.2-alpine3.19
- Externalize postgres credentials: hardcoded values → POSTGRES_USER/PASSWORD/DB env vars
- Externalize Grafana admin password: hardcoded 'agentidp' → GF_ADMIN_PASSWORD env var
- Add Docker Compose Variables section to environment-variables.md (POSTGRES_*, GF_ADMIN_PASSWORD)
- Update local-development.md Step 3: cp .env.example .env, document POSTGRES_* purpose
- Update quick-start.md: cp .env.example .env, use awk/sed for JWT key injection
- Update 07-dev-setup.md: remove 'no .env.example' claim, reference cp .env.example
- Update docker-compose.yml key file description in 04-codebase-structure.md
- Update monitoring overlay launch commands across all docs (compose.yaml + compose.monitoring.yaml)
- Update volume names to kebab-case: postgres_data → postgres-data, redis_data → redis-data
- Fix compliance encryption-runbook: docker-compose restart agentidp → docker compose restart app

All docs now consistent with compose.yaml in repo root.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 08:27:37 +00:00

7.1 KiB

Quick Start — Register Your First Agent

This guide gets you from zero to a working agent identity inside an organization, with a valid OAuth 2.0 access token. It takes under 5 minutes.

Prerequisites

You need two tools installed:

  • Docker (with Compose plugin, v2.20+) — to run PostgreSQL and Redis
  • Node.js 18+ (includes npm) — to run the server
  • curl — to call the API

Nothing else. No accounts, no sign-ups.


Step 1 — Clone and configure

git clone https://git.sentryagent.ai/vijay_admin/sentryagent-idp.git
cd sentryagent-idp
npm install

Generate an RSA keypair for signing tokens (required):

# Generate private key
openssl genrsa -out private.pem 2048

# Extract public key
openssl rsa -in private.pem -pubout -out public.pem

Copy the environment template and fill in your JWT keys:

cp .env.example .env

Write your JWT keys into .env:

PRIVATE_KEY_LINE=$(awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' private.pem)
PUBLIC_KEY_LINE=$(awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' public.pem)
sed -i "s|JWT_PRIVATE_KEY=.*|JWT_PRIVATE_KEY=\"${PRIVATE_KEY_LINE}\"|" .env
sed -i "s|JWT_PUBLIC_KEY=.*|JWT_PUBLIC_KEY=\"${PUBLIC_KEY_LINE}\"|" .env

Note

: The .env file stores your private key. Do not commit it to version control.


Step 2 — Start infrastructure

Start PostgreSQL and Redis using Docker Compose (infrastructure services only):

docker compose up -d postgres redis

Expected output:

[+] Running 2/2
 ✔ Container sentryagent-idp-postgres-1  Healthy
 ✔ Container sentryagent-idp-redis-1     Healthy

Services are ready when both show Healthy. Run migrations:

npm run db:migrate

Expected output:

Running database migrations...
  ✓ Applied: 001_create_agents.sql
  ✓ Applied: 002_create_credentials.sql
  ✓ Applied: 003_create_tokens.sql
  ✓ Applied: 004_create_audit_log.sql

Migrations complete. 4 migration(s) applied.

Step 3 — Start the AgentIdP server

npm run dev

Expected output:

SentryAgent.ai AgentIdP listening on port 3000
Database pool connected
Redis client connected

The API is now live at http://localhost:3000/api/v1.


Step 4 — Generate a bootstrap token

All API endpoints require a Bearer token. For first-time setup, generate a bootstrap token using your RSA private key:

node -e "
const jwt = require('jsonwebtoken');
const fs = require('fs');
const { v4: uuidv4 } = require('uuid');
const key = fs.readFileSync('private.pem', 'utf8');
const now = Math.floor(Date.now() / 1000);
const token = jwt.sign({
  sub: 'bootstrap',
  client_id: 'bootstrap',
  scope: 'agents:read agents:write tokens:read audit:read',
  jti: uuidv4(),
  iat: now,
  exp: now + 3600
}, key, { algorithm: 'RS256' });
console.log(token);
"

Copy the token output and export it:

export BOOTSTRAP_TOKEN="<paste token here>"

This bootstrap token is a one-time tool for registering your first agent. Once you have an agent with credentials, use POST /token for all subsequent authentication.


Step 5 — Create an organization

Agents are scoped to organizations. Create one now so your agent has an organization_id to belong to:

curl -s -X POST http://localhost:3000/api/v1/organizations \
  -H "Authorization: Bearer $BOOTSTRAP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My AI Project",
    "slug": "my-ai-project"
  }' | jq .

Example response (201 Created):

{
  "organizationId": "org-0a1b2c3d-e4f5-6789-abcd-ef0123456789",
  "name": "My AI Project",
  "slug": "my-ai-project",
  "planTier": "free",
  "maxAgents": 10,
  "maxTokensPerMonth": 10000,
  "status": "active",
  "createdAt": "2026-04-04T09:00:00.000Z",
  "updatedAt": "2026-04-04T09:00:00.000Z"
}

Save the organizationId:

export ORG_ID="org-0a1b2c3d-e4f5-6789-abcd-ef0123456789"

Step 6 — Register an agent

curl -s -X POST http://localhost:3000/api/v1/agents \
  -H "Authorization: Bearer $BOOTSTRAP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "my-first-agent@myproject.ai",
    "agentType": "custom",
    "version": "1.0.0",
    "capabilities": ["data:read"],
    "owner": "my-team",
    "deploymentEnv": "development",
    "organization_id": "'$ORG_ID'"
  }' | jq .

Example response (201 Created):

{
  "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "email": "my-first-agent@myproject.ai",
  "agentType": "custom",
  "version": "1.0.0",
  "capabilities": ["data:read"],
  "owner": "my-team",
  "deploymentEnv": "development",
  "status": "active",
  "createdAt": "2026-03-28T09:00:00.000Z",
  "updatedAt": "2026-03-28T09:00:00.000Z"
}

Save the agentId:

export AGENT_ID="a1b2c3d4-e5f6-7890-abcd-ef1234567890"

Step 7 — Generate a credential

curl -s -X POST "http://localhost:3000/api/v1/agents/$AGENT_ID/credentials" \
  -H "Authorization: Bearer $BOOTSTRAP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}' | jq .

Example response (201 Created):

{
  "credentialId": "c9d8e7f6-a5b4-3210-fedc-ba9876543210",
  "clientId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "clientSecret": "sk_live_7f3a2b1c9d8e4f0a6b5c3d2e1f0a9b8c",
  "status": "active",
  "createdAt": "2026-03-28T09:00:00.000Z",
  "expiresAt": null,
  "revokedAt": null
}

Save the clientSecret now. It is shown once and never retrievable again. The server stores only a bcrypt hash.

export CLIENT_ID="a1b2c3d4-e5f6-7890-abcd-ef1234567890"   # same as AGENT_ID
export CLIENT_SECRET="sk_live_7f3a2b1c9d8e4f0a6b5c3d2e1f0a9b8c"

Step 8 — Issue an access token

Use the OAuth 2.0 Client Credentials flow. Note that the /token endpoint uses form-encoded body, not JSON:

curl -s -X POST http://localhost:3000/api/v1/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=$CLIENT_ID" \
  -d "client_secret=$CLIENT_SECRET" \
  -d "scope=agents:read agents:write" | jq .

Example response (200 OK):

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "agents:read agents:write"
}
export TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

Your agent now has a valid JWT. Use it in the Authorization: Bearer <token> header for all API calls.


What's next

  • Core Concepts — understand AgentIdP, AGNTCY, orgs, DID, delegation, and tiers
  • Guides — step-by-step walkthroughs for all workflows
  • API Reference — every endpoint documented with curl examples

New guides for Phase 6 features: