Compile service
rivet-server is an HTTPS service that compiles catalogs for hosts. A host running rivet run in server mode sends its facts and a credential. The service verifies the credential, checks that the host may use the requested environment, compiles the environment’s release, and returns the catalog. The host then verifies the assets and applies the catalog itself. The service never changes managed hosts.
The server configuration uses the same literal-only format as the agent configuration, shown here as plain text. Keep it outside the published source directory.
GCP instance identity
This assumes port 443 on rivet.example.com forwards to the listener on 8443. The listener always uses TLS. The service’s own storage credentials need read access to the source; they are independent of how hosts authenticate. S3 sources work too.
The service verifies the token’s signature against Google’s keys, along with its issuer, audience, lifetime, verified service-account email, project, and full instance identity. Each request gets:
- a principal,
gcp:service-account:<email>, which allow rules match; - a node identity,
gcp:instance:<project>:<zone>:<instance-id>.
Authorizing a service account admits every VM that runs as it. Add target_identity to a rule (see authorization) to bind it to one machine.
mTLS
Keep listen, source, and tls from above, and replace the authentication and allow rules:
Here ca_file is the CA for client certificates. Each client certificate must contain exactly one URI SAN starting with urn:rivet:node:. That URI is the node identity, and the principal is mtls:uri: followed by the URI. TLS must terminate at rivet-server; certificate headers forwarded by a proxy are ignored.
crl_file is optional and enables revocation checks. Certificates, CAs, and CRLs load at startup, so restart the service to pick up new ones. Issuing and renewing client certificates is up to your deployment.
trusted_extensions is optional. It names certificate extension OIDs to expose as trusted claims, such as trusted.claims.extensions.role. Replace the example OIDs with ones from your own namespace. Values must be UTF-8 strings of at most 4 KiB, and at most 64 extensions can be mapped. Your CA must control these values: if it signs whatever role a host asks for, hosts can choose their own classification.
OIDC
The issuer must sign tokens with RS256 and publish keys at an HTTPS JWKS URL. Tokens must be valid for at most one hour. The principal and node identity are both oidc:<issuer>:<subject>. Keys are refreshed every five minutes. A token signed with an unknown key triggers an earlier refresh, at most once every 30 seconds. Configure the host’s token file and keep it fresh with your workload identity system.
On AWS, use mTLS or an OIDC workload token to authenticate, and IAM credentials for storage reads. Rivet doesn’t accept SigV4 requests or EC2 instance identity documents.
Authorization
Requests are denied unless an allow rule matches. Each rule has a unique name, an exact principal, and the environments it may use. Add target_identity to bind a rule to one machine’s hashed identity, copied from that host’s facts (target.identity). That is an extra check on top of credential authentication, not a replacement.
Facts submitted by a host are inventory only. Configuration sees the verified identity through the separate trusted namespace, which only the service can populate.
Source files, catalogs, and cached assets can all contain secrets in plain text. Protect the service host, its cache, and storage write access as carefully as host credentials.
Signed asset delivery
By default, hosts download assets from storage with their own credentials. To remove that requirement, add:
The service then returns signed GET URLs, valid for signed_asset_ttl_secs seconds (1 to 3600, default 900). This needs an S3 or GCS source and service credentials that can sign URLs; on GCS, a service-account key or IAM signing permission. Every external asset must belong to the release, so arbitrary cloud objects can’t be delivered this way.
If URLs expire before the host finishes downloading, the agent can ask once for fresh URLs for the same catalog. A refresh never picks up a newer release. Refresh grants last an hour and are lost when the service restarts. Signed URLs and tickets are never stored in caches, reports, or journals.
Settings and limits
Configuration and PEM files follow the agent’s file permission rules. Changes to configuration, TLS material, allow rules, or CRLs take effect after a restart.
Plugins
The service loads approved plugin definitions and functions from /etc/rivet/plugins.lock.json, or the file passed with --plugin-lock. A release can require plugins, but can’t install or approve them. Plugin hooks and functions run as the service user and must be pure. Hosts install their own runtime plugins separately; function-only plugins need nothing on the host, because results are compiled into the catalog.
Protocol
The service exposes POST /v1/compile and POST /v1/assets/refresh. rivet run is the supported client, and the protocol is experimental. Compile responses carry Cache-Control: no-store. Service failures never trigger source-mode or offline fallback.
The repository’s distribution checks use local fixtures, so test cloud credentials, signing, and IAM policy in your own deployment.