SDK Reference
Authentication

Authentication

Grounded now supports API-key auth on the SDK-backed /api/* routes without replacing dashboard session auth.

That means:

  • the dashboard can continue using BetterAuth sessions
  • scripts and services can use API keys
  • the SDK does not need browser cookies or dashboard login state

Key Types

KindPrefixIntended PackageNotes
secretgrd_sk_...@grounded/clientcan be tenant-scoped or agent-scoped
publishablegrd_pk_...@grounded/tracingmust be agent-scoped and trace-only

Scopes

Grounded checks both the key kind and the key scopes.

Available scopes today:

  • agents:read
  • agents:write
  • connectors:read
  • connectors:write
  • sessions:read
  • insights:read
  • snapshots:read
  • snapshots:write
  • jobs:read
  • jobs:write
  • job_loops:read
  • job_loops:write
  • evals:read
  • evals:write
  • traces:read
  • traces:write

Route Families

Route familyRequired scopeAllowed kinds
/api/agentsagents:read or agents:writesecret
/api/connectorsconnectors:read or connectors:writesecret
/api/sessionssessions:readsecret
/api/insightsinsights:readsecret
/api/snapshotssnapshots:read or snapshots:writesecret
/api/jobsjobs:read or jobs:writesecret
/api/job-loopsjob_loops:read or job_loops:writesecret
/api/evalsevals:read or evals:writesecret
/api/tracestraces:read or traces:writepublishable, secret

Publishable keys are intentionally narrow. They are for trace ingestion and trace readback, not for creating agents, snapshots, jobs, or connectors.

Scope Resolution

The API checks auth in this order:

  1. valid dashboard session
  2. valid bearer API key

If neither exists, the request is rejected.

If a key is present:

  • its prefix identifies the record family
  • the stored secret hash must match
  • expired keys are rejected
  • revoked keys are rejected
  • route kind restrictions are enforced
  • route scope restrictions are enforced

Tenant-Scoped vs Agent-Scoped

Secret keys can be:

  • tenant-scoped
  • agent-scoped

Agent-scoped keys are safer for service-to-service access because they can only operate on one agent.

Publishable keys must be agent-scoped.

Creating Keys

Key creation currently lives behind internal, session-authenticated routes:

  • GET /api/api-keys
  • POST /api/api-keys
  • POST /api/api-keys/:keyId/revoke

Secret Key Example

POST /api/api-keys
Content-Type: application/json
 
{
  "kind": "secret",
  "label": "ops worker",
  "scopes": [
    "connectors:read",
    "connectors:write",
    "sessions:read",
    "snapshots:read",
    "snapshots:write",
    "jobs:read",
    "jobs:write",
    "evals:read"
  ]
}

Publishable Key Example

POST /api/api-keys
Content-Type: application/json
 
{
  "kind": "publishable",
  "label": "support tracing",
  "agentId": "agt_123",
  "scopes": ["traces:write"]
}

SDK Usage

@grounded/client

import { Grounded } from '@grounded/client';
 
const grounded = new Grounded({
  apiKey: process.env.GROUNDED_SECRET_KEY!,
  baseUrl: 'http://localhost:3001',
});

@grounded/tracing

import { GroundedTracing } from '@grounded/tracing';
 
const tracing = new GroundedTracing({
  publishableKey: process.env.GROUNDED_PUBLISHABLE_KEY!,
  baseUrl: 'http://localhost:3001',
});

Operational Notes

  • @grounded/client sends Authorization: Bearer grd_sk_...
  • @grounded/tracing sends Authorization: Bearer grd_pk_...
  • API-key access is intentionally limited to the SDK-backed route families above
  • key management itself is not exposed through the SDK yet

Recommendations

  • use agent-scoped keys for individual services whenever possible
  • keep publishable keys trace-only
  • rotate keys instead of reusing one broad tenant secret everywhere
  • prefer separate keys for CI, backend APIs, and long-running workers