Skip to main content

Sharing secrets between tenants

This How-to assumes you know how to create vaults and secrets.

When a tenant is sharing a service with other tenants and the service requires client authentication, secrets must be shared. This can be achieved in two steps, the first step is to give access to a vault to another tenant using allow-tenant-access. The second step is that the application that wants to access this vault needs to specify which tenant that has the secret that one wants to access using from-tenant in the vault-secret or the value-from-secret section.

Here is an example: assuming platform-team will share a service with application-team-a and application-team-b.

Expose the secret to a list of named tenants:

credential secret (platform-team)
name: credentials
data:
password: reallysecret
user: admin
allow-application-access:
- "*"
allow-tenant-access:
- application-team-a
- application-team-b
EOF

The corresponding payload for a certificate secret:

certificate secret (platform team)
name: cert
auto-cert:
issuing-ca: my-app-ca
ttl: 30d
host: my-app
cert-type: server
allow-application-access:
- "*"
allow-tenant-access:
- application-team-a
- application-team-b
note

To share with all tenants:

allow-tenant-access:
- "*"

Now the application teams can mount the secret into their applications as usual, but must specify the tenant providing the secret.

application team application
name: app-team-as-amazing-app
services:
- name: the-service
volumes:
- name: cert
vault-secret:
vault: my-app
secret: cert
from-tenant: platform-team
variables:
- name: MY_USER
value-from-vault-secret:
vault: my-app
secret: credentials
key: user
from-tenant: platform-team

Granting configuration access to a secret​

A secret can be read by configuration objects, not only by applications: webhooks and OTel exporters read secrets through their variables, remote registries through their vault and secret credentials, and ACME external account binding keys through hmac-key-from-vault. Which configuration may read a secret, and from where, is decided by the secret's allow-config-access list. Each entry names a REST path starting with /v1/config/. As in API policies, * matches one path component, pre* a component that starts with pre, and ** as the last component the rest of the path. A path that matches no configuration, for example a misspelled one, is refused. An entry grants the tenant owning the secret; tenants extends it to other tenants, or to all of them with *.

The paths are:

ConfigurationPath
Webhook variable/v1/config/volga/webhooks/<name>/variables/<variable>
OTel metric exporter variable/v1/config/volga/otel-metric-exporters/<name>/variables/<variable>
OTel log exporter variable/v1/config/volga/otel-log-exporters/<name>/variables/<variable>
Remote registry credentials/v1/config/image-registry/remote-registries/<address>/credentials/<repository>
ACME external account binding key/v1/config/strongbox/tls/ca/<ca>/acme/eab-keys/<kid>/hmac-key
API token read by two webhooks (platform-team)
name: api-token
data:
value: 2c0a…
allow-config-access:
- path: /v1/config/volga/webhooks/*/variables/TOKEN
tenants:
- application-team-a

allow-config-access is separate from allow-tenant-access, which still governs cross-tenant application variables and the from-tenant of exporter variables; granting one does not grant the other. The owning tenant is granted by an entry's path alone, but only for the paths listed.

Transition

In this release a webhook or exporter variable, registry credential or ACME key that reads a secret without a matching allow-config-access entry still works, but raises the alert vault-config-access-missing on the reading tenant and, when the secret belongs to another tenant, on the owning tenant too. The alert carries the vault, the secret and the exact path to add, and clears once the read finds a matching entry. A coming release refuses such reads, so add the entries while the alert is only a warning.

note

A merge on allow-config-access keeps entries not mentioned, since the list is keyed by path. To revoke a grant, replace the secret with the entries that should remain.