Authentication
API key lifecycle, Bearer transport, and why the client never sends a tenant id — Radicas' anti-spoof tenancy model.
API key lifecycle
- Your ingest key (
rad_...) is issued once at onboarding by the Radicas wizard and shown a single time — store it in your secret manager, not in code or.envfiles committed to git. - The key identifies your tenant at the ingest gateway; rotating it in the Radicas console invalidates the old key.
- The SDK reads it from
RADICAS_API_KEY(recommended) or theapi_key=kwarg.
export RADICAS_API_KEY=rad_... # the onboarding snippetBearer transport
The key travels as a standard HTTP header on every OTLP export (gRPC metadata or HTTP header, depending on protocol):
Authorization: Bearer rad_...The SDK builds this header for you (it writes OTEL_EXPORTER_OTLP_HEADERS — see
configuration). Always use TLS endpoints (https://...) in ONLINE mode —
the default https://ingest.radicas.io is TLS-only.
Tenant semantics: the client never sends the tenant
This is a deliberate security property, not a missing feature.
In ONLINE mode the SDK never sends a tenant id. The ingest gateway resolves your tenant
from the API key and strips any client-sent tenant value before storage. The SDK cooperates
by never emitting radicas.tenant_id when a key is present — but the enforcement is
server-side, so it holds even for clients that do not cooperate.
Why it matters:
- Anti-spoof. If tenancy came from a client-writable attribute, any sender could attribute its token spend — or its garbage — to another tenant. Cost allocation, billing reconciliation, and per-tenant dashboards would all be forgeable.
- One source of truth. The key → tenant mapping lives in one place (the gateway), so key rotation, revocation, and auditing stay coherent.
- No configuration to get wrong. There is no tenant id to mistype into a deploy manifest.
The LOCAL lab exception
The local lab has no gateway and no keys, so there the tenant travels as a
resource attribute: the SDK stamps radicas.tenant_id from RADICAS_TENANT_ID (legacy
fallback TENANT_ID, default radicas-lab). This is a lab shim only — the moment an API key
is present, the SDK stops sending it and the gateway takes over.
| LOCAL lab | ONLINE | |
|---|---|---|
| Tenant carried by | radicas.tenant_id resource attribute | the API key (gateway-resolved) |
| Client-sent tenant | required (lab shim) | ignored and stripped by the gateway |
Key hygiene
- Never commit keys to the repo, bake them into images, or log them.
- One key per environment (dev/staging/prod) so rotation has a small blast radius.
- A
401in the exporter logs means the key is missing, revoked, or malformed — see troubleshooting.
Configuration
Full reference for radicas.init() — every kwarg, its RADICAS_* environment twin, defaults, precedence, and the underlying OTEL_* contract.
Feature tagging
Attribute agent cost to product features and users — the default feature, radicas.feature() scoping, and radicas.user() for per-user allocation.