Skip to main content
API keys authenticate applications calling Hivenet Router’s /v1/* endpoints. Hivenet Router hashes every submitted key with SHA-256 and compares the result with a stored hash. The router does not need to retain the raw client key. Two key-management modes are available:
Administration keys are separate from client API keys. Client keys do not grant access to /admin/*.

Choose a key mode

Use static mode when:
  • keys change infrequently
  • operators manage configuration files directly
  • file-based review and version control fit your workflow
  • keys should be restored automatically after a router restart
Use dynamic mode when:
  • another service owns the key lifecycle
  • keys need to be created, disabled, or revoked at runtime
  • the router must receive full-registry reconciliation from a control service
  • you do not want static client-key entries in auth.yaml
Changing between static and dynamic mode requires a router restart.

Key format

The built-in key generator creates keys with:
Each generated key contains 32 random bytes before Base58 encoding. Hivenet Router stores three related values: A preview resembles:
The preview is not used to authenticate requests.
The raw key is shown once during generation. If it is lost, generate another key rather than trying to recover it from the hash.

Generate a static key

Run:
To assign an owner name immediately:
The command prints:
  • the raw key
  • its SHA-256 hash
  • its masked preview
  • an auth.yaml entry
A shortened example resembles:
Store the raw key before closing the terminal.

Configure a static key

Create an auth file such as:
Start the router with:
The environment-variable equivalent is:

Static key fields

Duplicate key_hash values are rejected when static configuration is loaded. Use the exact lowercase SHA-256 output produced by hivenet-router keygen or sha256sum. Do not edit a hash manually. metadata.name and metadata.owner must not be empty.

Static key expiration

Static keys use:
For example:
The key remains valid through January 1, 2027, UTC. It becomes invalid at:
An empty or omitted value means the key does not expire. Expired and unknown keys produce the same generic 401 unauthorized response.

Use a client key

Send the raw key with the standard bearer header:
For example:
Hivenet Router also accepts the raw value without the Bearer prefix, but use the standard format for applications, proxies, and SDKs.

OpenAI Python client

Set the key outside the source code:

Restrict models

A static key can declare an exact model allowlist:
An empty or omitted list means access to every registered model:
Model names are exact and case-sensitive. A request for a disallowed model returns HTTP 403:
Model discovery is filtered as well. GET /v1/models returns only models that the key may use. See Model restrictions for multi-tenant examples and discovery behavior.

Configure flat quotas

The flat quota shape applies one request and token budget to every model the owner may call.
The input and output rate fields apply only when the effective model policy uses mode: serverless. They cannot be combined with quota.per_model. A serverless key can also declare max_occupancy_share at the key level, alongside quota:
The value limits the key’s token-weighted work to share × admit_budget_tokens × healthy_replicas. It deliberately does not apply HIVENET_ROUTER_ADMIT_FRACTION; the global occupancy gate remains the pool-safety limit. For every reachable serverless model, a nonzero input_tokens_per_minute must be at least the policy’s max_input_tokens. The router validates this and the occupancy-share range at startup, during reloads, and on dynamic admin key writes. The auth.DeriveKeyDefaults helper can calculate suggested values from certified model limits. The current runtime does not load router_limits.yaml or apply those defaults automatically. The flat quota bucket is keyed by:
This has an important consequence:
Several keys with the same metadata.owner share the same flat request and token budgets.Use different owner values when keys require independent quota buckets.
The request-rate limiter uses a token bucket. It begins with up to one minute’s configured capacity and refills continuously rather than resetting at fixed clock-minute boundaries. Set HIVENET_ROUTER_RPM_BURST_SECONDS to a value from 1 through 59 to reduce the burst window; 0 preserves the full-minute capacity.
Dynamic keys have stable IDs, so serverless occupancy and token-rate state is isolated per key. Static-key authentication currently leaves the key ID empty, causing static keys to share the anonymous B4 state for a model. See the auth YAML reference before using static keys with serverless limits.
The daily token counter resets at midnight UTC.

Configure per-model quotas

Per-model quotas define separate budgets for each model:
Each entry must declare both fields. Use 0 explicitly when one limit should be unlimited. For example:
The effective request ceiling changes as healthy agents join or leave. When no healthy agent serves the model, Hivenet Router skips the rate-limit decision and lets routing return the more accurate availability error.

Per-model quotas are also an allowlist

When quota.per_model exists, its model names become the key’s effective model allowlist. For example:
allows only:
This remains true even when models contains other names. quota.per_model takes precedence so quota configuration and access control cannot disagree. A request for a model without a quota entry is rejected rather than falling through to an unlimited default.

Do not mix quota shapes

This is invalid:
Choose either:
  • the flat shape
  • the per-model shape
Hivenet Router rejects a key that mixes them.

How token budgets work

Daily token limits currently apply to language-model chat requests. At admission, Hivenet Router:
  1. estimates prompt tokens
  2. reads max_completion_tokens, or falls back to max_tokens
  3. checks whether the estimated prompt and requested maximum output fit in the remaining budget
  4. charges the prompt estimate when the request is admitted
After a non-streaming backend response, Hivenet Router charges the actual completion-token count. If the completion no longer fits in the remaining budget, Hivenet Router discards the response and returns HTTP 429. The previously charged prompt estimate remains counted. For streaming responses, the bytes may already have reached the client before the final completion-token total is known. Hivenet Router records the output usage after the stream finishes, but it cannot retract an already delivered stream.
Embedding and reranking requests currently participate in request-rate quotas but do not charge their input against tokens_per_day.

Rate-limit headers

Finite quotas may produce:
Unlimited values do not produce a remaining-value header. Request-rate exhaustion returns HTTP 429 with:
and the code:
Token-budget responses require more care:
  • a preflight rejection can return a positive X-RateLimit-Remaining-Tokens value when the remaining budget exists but cannot admit the request’s estimated input plus requested maximum output
  • a post-response token rejection returns X-RateLimit-Remaining-Tokens: 0
  • unlimited token budgets omit the header
Both token cases use:
The human-readable message varies according to the stage. Use error.code and the remaining headers rather than matching message text.

Choose quota persistence

Request-rate state is always kept in memory. Daily token usage can use either: The default is:
Enable persistence:
or in Docker Compose:
The router’s disk database must be configured and writable. Badger-backed daily counters use a 48-hour record lifetime so the current day survives restarts without accumulating old quota records indefinitely.

Reload static keys

After editing auth.yaml, send:
Hivenet Router:
  1. parses and validates the new file
  2. builds replacement authentication providers
  3. swaps them atomically
  4. rebuilds the in-memory quota limiter state
  5. keeps the previous configuration when reload validation fails
In-flight requests continue using the provider they already reached.
Request-per-minute buckets reset after a successful authentication reload.With the memory quota backend, current daily token usage also resets. With the badger backend, Hivenet Router flushes daily token state before rebuilding the limiter and restores it on later requests.
SIGHUP cannot switch between static and dynamic client-key modes. Restart the router to change modes.

Enable dynamic mode

Dynamic mode keeps client keys in an in-memory registry managed through /admin/api-keys/*. Enable it with:
You may also set:
in auth.yaml. Administration authentication is mandatory in dynamic mode. The router refuses to start without:
The dynamic registry starts empty. An external control service must populate it before client requests can authenticate.

Create a hash for a dynamic key

The dynamic API accepts the SHA-256 hash, not the raw bearer key. You can use the built-in key generator and take the printed hash, or hash a key created by your control service:
A dynamic key_hash must contain exactly 64 hexadecimal characters. Hashes are normalized to lowercase.

Bootstrap the dynamic registry

Replace the complete registry:
The operation validates every entry before replacing the registry. A malformed entry prevents the entire replacement. The response is:
See Admin endpoints for individual add, update, delete, list, and reconciliation requests.

Dynamic key fields

Dynamic expiration uses RFC 3339:
Unlike static expiration, this is an exact instant rather than a final valid calendar day.

Dynamic registry versions

Every mutation includes an opaque version string. Hivenet Router compares versions lexicographically. Use values whose string ordering matches time ordering:
or:
A lower version is rejected as stale. An equal version is accepted. That makes replay possible, but the router does not prove that an equal-version payload is identical to the earlier one. Use a strictly newer version for every distinct intended registry state. The rule applies to:
  • single-key upserts
  • deletions
  • full-registry replacement
Do not use unpadded values such as:
because lexical ordering places rev_10 before rev_9.

Disable or revoke a dynamic key

To disable a key without removing its metadata, update it with:
A disabled key produces the same generic 401 unauthorized response as an unknown or expired key. To remove the entry, call:
Deletion is idempotent. Updating the same ID with a new hash immediately stops the old hash from authenticating. This supports one-step rotation, although an add-before-remove migration with two IDs is often safer for applications.

Dynamic registry visibility

Operators can list entries through:
and read one through:
Hivenet Router never returns the stored hash. The response includes:
for both enabled and disabled entries. The raw bearer key cannot be recovered from the registry.

Dynamic restart behavior

Dynamic key state is memory-only. After every router restart:
  1. the registry is empty
  2. every previous client key fails authentication
  3. the external control service must push a current snapshot
  4. the service can confirm state through /admin/api-keys/version
SIGHUP does not clear or replace the dynamic registry. It can reload the administration provider, but dynamic client keys remain under API control.

Admin keys are separate

Admin keys come from:
They are not stored under api.keys. The hivenet-router keygen output is designed for hashed client-key entries, while administrator keys remain raw environment secrets. Use an admin key:
Do not reuse a client key as an admin key. The router refuses to start with unauthenticated administrator endpoints unless HIVENET_ROUTER_ALLOW_INSECURE_ADMIN=true is set explicitly. Use that override only for isolated development and testing.

Security guidance

  • Store raw keys in a secret manager.
  • Never commit raw keys or .env files.
  • Give each application or integration its own key.
  • Use meaningful owners and names.
  • Keep model access as narrow as practical.
  • Set quotas that match the intended workload.
  • Use expiration for temporary credentials.
  • Use separate client and administration credentials.
  • Send keys only over HTTPS outside a trusted network.
  • Do not place keys in query strings.
  • Enable audit logging before production use.
  • Rotate keys without waiting for a suspected compromise.

Troubleshooting

Every request returns 401 unauthorized

Check that:
  • the router is using api-key or dynamic mode
  • the application sends the raw key rather than the hash
  • the Authorization header reaches the router
  • a static hash matches the exact raw key
  • the static key has not expired
  • the dynamic key is enabled
  • the dynamic registry has been repopulated after restart
Hivenet Router does not reveal which authentication condition failed.

A static key does not load

Check the router logs. Common causes include:
  • empty key_hash
  • empty metadata.name
  • empty metadata.owner
  • duplicate hashes
  • invalid expires_at
  • invalid quota configuration
  • empty api.keys while mode is api-key
The previous provider remains active when a SIGHUP reload fails.

A key can see the wrong models

Check whether the key uses:
or:
When quota.per_model exists, its keys define the effective allowlist and take precedence over models.

Several keys consume one quota unexpectedly

Check their owner values. Keys with the same:
share quota buckets. Assign different owners when the limits should remain independent.

The effective per-model RPM is unexpected

The rate is:
Check the current healthy replica count:

Daily usage resets after restart

The quota backend is probably using:
Enable:
to persist daily token use. Request-per-minute state remains in memory by design.

A dynamic update returns 409 stale version

Read the current registry version:
Retry with a version that sorts equal to or after the current one.

A dynamic update rejects the hash

Check that it is exactly 64 hexadecimal characters:
Do not send the raw key in key_hash.

Next steps

auth.yaml reference

Review the full static authentication and quota schema.

Model restrictions

Design model access for applications, tenants, and workload types.

Key rotation

Rotate static, dynamic, administration, agent, and provider credentials safely.