Skip to content

Super-admin

The super-admin tier — raise a tenant's ceilings, and read the operational activity, metrics, and diagnostics behind the X-Admin-Key.

Updated View as Markdown

The super-admin tier sits above every tenant. It authenticates with a single X-Admin-Key header and does two kinds of thing: raise a tenant’s ceilings, and expose read-only operational state — recent activity, a performance series, and instantaneous gauges — so an incident can be diagnosed from an HTTP client rather than a host sign-in. None of it appears on the public health probe.

Every route below shares the same auth. A missing or invalid key is 401 admin_denied; the tier is rate limited as a whole (429 admin_rate_limited).

POST /v1/admin/tenants/{id}/limits

Lift a tenant’s limits. Auth: X-Admin-Key. Returns 201.

{id} is the tenant id.

Request

{
  "maxWorkspaces": 50,
  "maxWallets": 2000
}
Field Type Required Notes
maxWorkspaces integer no New workspace ceiling. Non-negative
maxWallets integer no New wallet ceiling. Non-negative

At least one field is required; an empty body is 400. Only these two ceilings are liftable — maxUnlockedWorkspaces is deliberately out of reach. The raise is one-directional: a value below the current ceiling is refused with 409 limit_not_raised, never silently applied.

The change is persisted in state.json, so it survives a restart even though tenants.json is mounted read-only.

Response

{
  "tenant": "acme",
  "limits": { "maxWorkspaces": 50, "maxWallets": 2000 },
  "changed": ["maxWorkspaces"]
}

limits is the effective ceiling after the call; changed lists only the fields that actually moved, so a no-op raise returns an empty array.

Errors

Status Code
400 invalid_body, invalid_slug
401 admin_denied — a missing or invalid X-Admin-Key
404 tenant_not_found
409 limit_not_raised — the value is below the current ceiling (a value equal to it is accepted, changing nothing)
429 admin_rate_limited

GET /v1/admin/diagnostics

An instantaneous operational snapshot. Auth: X-Admin-Key. Returns 200.

Cheap in-process gauges — no locks, no tenant work. Uptime and core version; process memory, open file descriptors, and cumulative event-loop lag; live session and lease counts; and an activity block reporting the fill and drop counters of the activity log below.

{
  "uptimeSec": 37,
  "coreVersion": "<wative-core version>",
  "process": {
    "rssBytes": 118321152,
    "heapUsedBytes": 40286992,
    "heapTotalBytes": 43204608,
    "externalBytes": 3893242,
    "openFds": 23,
    "openFdLimit": 524288,
    "eventLoopLagMeanMs": 20.3,
    "eventLoopLagMaxMs": 196.35
  },
  "sessions": { "sessions": 0, "unlockedWorkspaces": 0, "unlockedWorkspacesCap": 32, "liveLeases": 0, "durableLeases": 0, "leasesPerWorkspaceCap": 64 },
  "activity": { "enabled": true, "eventsCaptured": 3, "eventsDropped": 0, "eventsHeld": 3, "eventCap": 2000, "perfSamplesHeld": 0, "perfCap": 900, "lastSeq": 3, "lastCrashHeld": 0 },
  "buffer": { "enabled": true, "batchSize": 50, "lowWatermark": 25 }
}

The event-loop figures here are cumulative over the process lifetime, so they cannot place a stall in time. Use GET /v1/admin/metrics for a timestamped series. The buffer block reports whether wallet buffer mode is on (`BUFFER_SIZE

0`) and its dials, so the mode is confirmable without host access.

Errors

Status Code
401 admin_denied
429 admin_rate_limited

GET /v1/admin/activity

The recent-activity ring — a bounded, in-memory log of what the service has been doing. Auth: X-Admin-Key. Returns 200, cache-control: no-store.

One entry per HTTP request (method, route template, status, latency, request id, tenant, and any account or wallet binding), session open/close/evict events, and — for every error — the internal reason the response body and the warning log deliberately omit. That last field is what lets a failure be diagnosed by its request id alone.

Query

Field Type Notes
limit integer Max events returned, newest kept. Optional
kind string Filter by kind — one of request, error, session, mint, lease, ratelimit, provision, lifecycle, fatal; any other value is 400 invalid_body. Optional
sinceSeq integer Only events with a higher seq — feed the previous response’s lastSeq back for a gap-free incremental tail. Optional
scope string current (default) reads the live ring; lastcrash reads the previous run’s reloaded dump

Response

{
  "events": [
    {
      "seq": 42,
      "ts": 1789715615345,
      "kind": "request",
      "method": "POST",
      "route": "/v1/auth/token",
      "status": 401,
      "latencyMs": 6,
      "requestId": "53e33bc8-c052-4760-a617-47926dcca0db",
      "tenant": "acme"
    },
    {
      "seq": 43,
      "ts": 1789715615346,
      "kind": "error",
      "code": "session_expired",
      "status": 401,
      "reason": "no token lifetime remains",
      "requestId": "53e33bc8-c052-4760-a617-47926dcca0db"
    }
  ],
  "lastSeq": 43
}

Fields are redacted as they enter the ring: bearer tokens, JWTs, API keys, and 32-byte hex secrets never reach it, and overlong values are capped. Wallet addresses and workspace/account slugs are recorded — they are admin-tier diagnostic aids, not secrets. Passwords and key material are never captured.

The ring is in memory and clears on restart, except that its tail is written to state/activity-crash.json on shutdown and from the fatal handler, then reloaded at boot and served under scope=lastcrash — so the events leading to a crash survive the restart.

Errors

Status Code
400 invalid_body — an unknown or malformed query parameter
401 admin_denied
429 admin_rate_limited

GET /v1/admin/metrics

The performance series. Auth: X-Admin-Key. Returns 200, cache-control: no-store.

A short, bounded time-series sampled on an interval: event-loop lag (mean and max per interval, so a stall lands on a timestamp), process memory, and file descriptor count.

Query

Field Type Notes
limit integer Max samples returned, newest kept. Optional

Response

{
  "samples": [
    {
      "ts": 1789715630419,
      "loopLagMeanMs": 20.16,
      "loopLagMaxMs": 21.2,
      "rssBytes": 118321152,
      "heapUsedBytes": 40410712,
      "externalBytes": 3893242,
      "openFds": 22
    }
  ]
}

Errors

Status Code
400 invalid_body
401 admin_denied
429 admin_rate_limited
  • Workspaces — where those ceilings are spent
  • Quota — a tenant reading its own usage against these limits
Navigation

Type to search…

↑↓ navigate↵ selectEsc close