Beacon Tenant Isolation¶
The beacon relay is a stateful TCP rendezvous point. It matches two outbound TLS connections by an opaque hash and forwards encrypted bytes between them. The relay does not hold the inner Port/broker tunnel keys or decrypt its payload; outer-TLS and tenant-authentication keys are separate relay assets. This end-to-end opacity means a key leak at the relay layer has an availability and pairing blast radius, never a confidentiality one.
This page documents the tenant isolation model that prevents co-tenants on a shared beacon from interfering with each other's pairing state.
Preview status
cloudtaser is in Preview. See Preview Status & Roadmap for the current audit and certification timeline. This page describes the tenant isolation architecture, which is implemented in released components but not yet activated on the hosted relay.
Trust model of the relay¶
The beacon relay is end-to-end opaque. TLS terminates at the port (EU secret-store side) and at the operator broker (cluster side). The relay forwards ciphertext bytes via a raw bidirectional copy after the initial JSON registration exchange. It holds no private keys for either endpoint and cannot decrypt or inspect the port-broker mTLS session.
Pairing is based on a rendezvous hash:
Both the beacon-salt and the cluster fingerprint are per-cluster secrets stored in the secret store. An attacker must discover the victim's infoHash before any relay-layer attack is possible.
What a relay-layer key leak can and cannot do¶
Because the relay is opaque, the exposure from a shared registration key leak is strictly availability and pairing, never confidentiality:
| Exposure | Impact | Requires |
|---|---|---|
| Pairing-hijack DoS | Co-tenant claims the victim's tenant_id and re-registers with its infoHash, evicting the legitimate registration |
Shared key + victim's infoHash |
| Presence oracle | "matched" vs "waiting" response reveals whether a target cluster is currently online |
Shared key + victim's infoHash |
| Secret content disclosure | Not possible -- the inner port-broker mTLS session is opaque to the relay | N/A |
See the Beacon Trust Model for the full analysis of what the relay sees and cannot see.
Per-tenant key model¶
The per-tenant key model eliminates the shared-key cross-tenant exposure described above. Each tenant gets an independent 32-byte HMAC registration key. A co-tenant's key, the shared key, and the shared key's HKDF derivation all fail authentication for an explicitly keyed tenant.
Key issuance¶
cloudtaser-cli beacon tenant issue generates one independent 32-byte tenant registration key and delivers the same salt-free {tenant_id, auth_key} JSON record to two private inherited pipes -- one for the relay-side Secret Manager record, one for the source-side configuration. The pipes must be distinct, private, writable, numbered 3 or higher; stdout, stderr, regular files, and shared pipes are refused.
The beacon-salt is generated source-side during source configure --beacon-tenant-stdin and never reaches the relay. The relay record carries only the tenant ID and registration key.
Relay-side loading¶
The relay loads tenant keys from --tenant-auth-keys-file at startup. This file must be a strict-permission file (0400/0440) on a root-only tmpfs -- not on persistent disk. The file format is one tenant_id=base64-key per line, or a JSON object whose values are either a base64 key or {"key", "previous", "previous_until"} for bounded rotation overlap.
When a registration includes a tenant_id present in the tenant auth keys file, the relay verifies the token only with that tenant's configured key. No other tenant's key, no shared key, and no HKDF derivation of the shared key is ever a candidate for an explicitly keyed tenant -- on the public listener or on the HA forwarded path.
Wire v2 tenant registration¶
Both the port and the operator register with protocol v2 when tenant identity is configured. The tenant ID is canonicalized to lowercase via wire.CanonicalTenantID on both sides before use in registration.
- Port side:
--beacon-tenant-idor--beacon-tenant-from-secretstoreconfigures the tenant ID. The port reads the tenant record from the secret store, canonicalizes the ID, and includes it in every v2 registration. - Operator side: The operator's runtime bundle carries
tenant_id. The broker canonicalizes it withwire.CanonicalTenantIDand includes it in every v2 registration to the beacon.
After authentication, the relay constructs a tenant match domain using:
matchDomain = SHA256("cloudtaser-tenant-match:v2" || NUL ||
lowercase(tenant_id) || NUL || lowercase(effective_info_hash))
This tenant match domain is structurally separate from the legacy v1 match domain. Two tenants with the same raw infoHash remain in disjoint match, ownership, pending, redirect, rate-limit, and resumption namespaces. A co-tenant cannot match, replace, redirect to, rate-limit, or resume another tenant's rendezvous state.
Tenant key rotation¶
Tenant keys rotate with a bounded overlap instead of a flag day (expand, switch, contract):
- Expand: Deploy the new key as
keyand the old key aspreviouswith aprevious_untildeadline (at most 7 days ahead) to every beacon in the fleet via drained rolling restart. The file is read only at startup. - Switch clients: Move the tenant's client record to the new key and restart the clients. Monitor
cloudtaser_beacon_registrations_accepted_total{auth_source="tenant_previous"}until it stops rising. - Contract: Drop
previousandprevious_untilby a second drained rolling restart. After the deadline, old-key attempts are rejected asretired_auth_key.
A tenant's previous key authenticates only that tenant, only before its deadline, and is never a shared key, a shared-key derivation, or any other tenant's key.
Strict mode¶
--strict-wire-v2 requires a canonical explicit tenant key map with a distinct 32-byte key per tenant. Tenant rotation-overlap keys join the same distinctness domain, so no key -- current or previous -- authenticates more than one tenant. In strict mode:
- Unknown and missing tenants are rejected at construction
- v1 registrations are rejected
- Shared keys, previous shared keys, unauthenticated registration, and legacy HMAC overlap are all rejected
- Strict mode never accepts the shared key or its derivation, even if one is installed after construction (via activation, unseal, or admin rotation)
Strict mode is opt-in (default off). Enable it only after the accepted-registration census (cloudtaser_beacon_registrations_accepted_total{auth_source}) confirms that shared and tenant_derived counts have reached zero for the census window.
Hosted relay guardrail¶
Hosted demo offline until beta
The hosted demo is offline until beta. Hosted customer and pilot enrollment are unavailable; customers choose their own relay explicitly.
The historical demo relay at beacon.cloudtaser.io used shared-key mode with
one demo tenant. That record does not establish current availability or tenant
isolation. See the hosted demo status.
No second tenant may be onboarded to beacon.cloudtaser.io until per-tenant keys are enforced for it (Wire v2 tenant cutover). The first co-tenant on the shared key would turn the demo-local exposure into the cross-tenant pairing-hijack and presence-oracle exposure described above.
Customer installations, including pilots, require a customer-chosen relay with verified TLS and tenant-key/restart custody. Do not wait for hosted enrollment or reuse a demo identity. Use the signed standalone binary procedure; no relay Helm chart deployment is qualified here. See Beacon Installation for deployment instructions.
Current status¶
Per-tenant key support and Wire v2 tenant registration are implemented and released in:
- cloudtaser-beacon --
--tenant-auth-keys-file,--strict-wire-v2, tenant match domains, bounded key rotation - cloudtaser-port --
--beacon-tenant-id,--beacon-tenant-from-secretstore, v2 registration with canonical tenant ID - cloudtaser-operator -- Runtime bundle
tenant_id, v2 registration with canonical tenant ID - cloudtaser-cli --
beacon tenant issuefor key issuance over private pipes - cloudtaser-wire --
CanonicalTenantID,ComputeTenantMatchKey,DeriveTenantKey, protocol v2 constants
Strict tenant mode is not yet activated on the hosted relay. Production deployments that require tenant isolation today should deploy a dedicated beacon per trust boundary.
Related pages¶
- Beacon Trust Model -- what the relay sees and cannot see
- Beacon Relay -- how the relay works
- Beacon Installation -- deploying your own beacon
- Self-Bootstrap Protocol -- how the info_hash pin is established
- Zero Kubernetes Secrets -- why certs and keys are never on disk