RFDs/0023

Deployment identifiers and agent home resolution

State
discussion
Authors
Darwin D Wu
Discussion
renga-dcim/renga#179
Labels
rengaagentapisoftware
Implemented
0%Checklist

Goal

Let an agent be installed with one well-known address that answers "your Renga is here", so an operator who runs several deployments can give every installation the same configuration, and move an organization between deployments without touching its agents.

Today an agent’s configuration names its deployment URL and an organization intake key (RFD 3), and the agent sends every request to that URL. That is right for one deployment. An operator running several, one per region or one per customer, must hand each customer the URL of their deployment at install time, and when an organization moves to another deployment through export and import (RFD 20), every agent it has must be reconfigured, even though RFD 20 keeps the agents' installation identities and keys valid.

This RFD adds two small, generic pieces to Renga: a deployment identifier that intake keys carry in the open, and an agent that resolves its home deployment once and again whenever its home says it has moved. It does not define the resolver an operator runs at the well-known address; any service that answers the request below can be one, and a Renga deployment answers it for itself.

Deployment identifier

An operator may give a deployment an identifier through its environment: a short lowercase name of letters, digits, and hyphens, at most 16 characters, such as eu1 or acme. It is not secret and is meant to be read from a key by something that is not the deployment. A deployment without one behaves as today.

When a deployment has an identifier, the intake keys it issues carry it:

renga_intake_eu1_<secret>

The secret part keeps RFD 3's 32 random bytes, and only the whole key’s hash is stored, so the identifier is an annotation on the key, not part of its authentication. Keys issued before the identifier was set, or without one, stay valid unchanged. Authentication never trusts the identifier: a key with a wrong or missing identifier still authenticates by its hash, and a key with the right identifier and a wrong secret still fails. The identifier exists so that a resolver can read it without ever seeing the secret. An agent whose key predates the identifier keeps talking to its deployment directly; rotating the key, as RFD 3 allows, gives it one.

RFD 22's operator API and renga release commands report the deployment’s identifier, and an organization’s intake key page shows the identifier its keys carry.

Home resolution

The request

Every deployment answers one unauthenticated request:

GET /api/v1/agent/home?deployment=<identifier>

It returns 200 with the deployment’s own public URL as home, the URL it is configured to be reached at, regardless of the identifier asked for: a deployment is its own home. The request carries no credential, and the response carries nothing else. A resolver at a well-known address answers the same request by looking the identifier up and returning that deployment’s URL, or 404 when it knows none. Renga does not define the resolver.

What the agent does

The agent’s renga_url becomes the address it resolves from, which may be a deployment or a resolver. The agent keeps a persisted home in its state directory beside its installation identity (RFD 3):

  1. On start, when no home is persisted, the agent reads the deployment identifier from its intake key’s prefix and sends the home request to renga_url. A key without an identifier is sent with an empty deployment parameter, which a deployment answers with itself and a resolver answers with 404. The agent persists the returned home and sends every other request there.

  2. The agent never sends an authenticated request to renga_url itself unless renga_url is its home. Its intake key goes only to the home it resolved.

  3. A home must be an https URL unless the agent is configured with allow_insecure_http, as renga_url is today, and the agent trusts the home for the same reason it trusts renga_url: both are reached over TLS to a name the operator wrote into its configuration or that this name vouched for.

  4. The agent’s transport keeps following no HTTP redirects. The home response is an ordinary 200 body, so an operator’s reverse proxy cannot redirect an authenticated request elsewhere.

Moving

When an organization has been exported from one deployment and imported into another (RFD 20), the source deployment’s organization is left moved, and its intake endpoints answer requests carrying its keys with 410 Gone and {"error": "moved"}, distinct from the 403 a suspended organization returns (RFD 22). RFD 20's import marks the source organization moved as its last step, so a moved organization is one whose data exists elsewhere.

On 410 moved, the agent discards its persisted home and resolves again from renga_url. If resolution returns the same home, the agent treats it as transient and backs off with its normal retry policy; a resolver that has not caught up yet is not a reason to drop data, and the agent’s durable queue holds observations meanwhile. Once a different home is returned, the agent continues there with the same installation identity, which the import preserved. No other status triggers resolution: 401 and 403 mean the key is wrong, revoked, or suspended, and re-resolving would not change that.

An operator can also force resolution by deleting the persisted home. The agent logs the configured renga_url, the resolved home, and when it was resolved at startup and after every resolution.

Security

  • The resolver sees the deployment identifier and the agent’s address, nothing else. It cannot authenticate as the agent or read its data.

  • The home request is unauthenticated and cheap, and a deployment answers it with a constant, so it is rate limited per source address like any other unauthenticated request (RFD 21).

  • Pointing an agent at a hostile resolver sends its key to the hostile home that resolver names. That is the same trust an agent places in renga_url today, and the mitigation is the same: renga_url is set by the operator and reached over TLS.

  • A deployment answers the home request with its configured public URL, never with anything derived from the request, so the request cannot be used to redirect other agents.

Amendments

  • RFD 3: intake keys may carry a deployment identifier between the fixed prefix and the secret; authentication ignores it.

  • RFD 20: completing an import marks the source organization moved, and a moved organization’s intake endpoints answer 410 Gone with moved.

  • RFD 22: the deployment identifier is part of deployment configuration, and the operator API reports it.

Future work

  • A home response that carries more than the URL, such as a second address to try, once an operator needs it.