Secrets¶
EngFlow supports secrets: confidential key-value pairs that may be passed to remotely executed actions as environment variables. Secrets are never stored in content addressable storage (CAS) in plaintext.
Types of secrets¶
- A tenant secret is a key-value pair managed by a user administrator through the
SecretgRPC API. Tenant secrets are shared by all users with access to a tenant, if authorized by their permissions. This means tenant secrets are appropriate for values not specific to any user, like external Docker registry credentials or shared bot account keys. On multitenant clusters, secrets in one tenant are isolated from other tenants. On single tenant clusters (most clusters), secrets are effectively global. - An on-demand secret is a unique secret generated for each action when it is requested. Currently only the
ENGFLOW_RPC_CREDENTIALSsecret is supported.
Service configuration¶
The following flags must be set in the scheduler's configuration file to enable secrets:
--enable_tenant_secrets=trueto enable tenant secrets--enable_ondemand_secrets=ENGFLOW_RPC_CREDENTIALSto enable theENGFLOW_RPC_CREDENTIALSon-demand secret
If you're interested in using secrets, contact support to enable these flags.
Permissions and roles¶
Access to secrets is managed through EngFlow roles, permissions, and policies. There are three permissions relevant to tenant secrets:
secret:Read: list secret names withListand read values of secrets withGet.secret:Write: create or update secrets withSetor delete secrets withDelete.secret:Execute: execute actions using secrets.
When writing policies, use the resource name secret/{NAME} to grant access to a specific secret, replacing {NAME} with the secret name.
The following built-in roles have access to secrets by default:
- The
userrole hassecret:Executepermission on all secrets in thedefaulttenant. - The
adminrole has all permissions in thedefaulttenant. - The
global-adminhas all permissions on all tenants.
Manage tenant secrets with the Secret API¶
The Secret gRPC API is defined in secret.proto. It supports four operations:
List: get names of all secrets within a tenant. Supports pagination.Get: read the value of a particular secret.Set: create a new secret or update an existing secret's value.Delete: delete a secret.
Execute actions with secrets¶
To execute an action with secrets, set the engflow:secrets platform property to a comma-separated list of secret names. The action will execute with environment variables set to secret values. For example, if the DOCKER_CREDS secret is requested, an environment variable named DOCKER_CREDS is set to its value. The client must have secret:Execute permission to access all requested secrets.
To request secrets for a specific Bazel target, set its exec_properties:
To request a secret for all actions from the Bazel command line, use --remote_default_exec_properties:
The value of the secret is only available at run-time and is not stored in plaintext in content addressable storage (CAS) or the action cache (AC). However, the name of each requested secret is stored in CAS. An action that uses secrets may be cached, though secret values are not cached unless the action writes them to output files. Changing the value of a secret does not invalidate AC entries for actions that executed using the old value, so rotating a secret won't cause a performance penalty.
Access the cluster within an action with ENGFLOW_RPC_CREDENTIALS¶
To execute an action that can access the EngFlow cluster, request the secret ENGFLOW_RPC_CREDENTIALS using one of the methods above. This is an on-demand secret: it does not need to be stored ahead of time. When requested, the ENGFLOW_RPC_CREDENTIALS environment variable is set to a bearer token that can be used to authenticate to an EngFlow cluster.
To use the token within an action, set the x-engflow-auth-method gRPC metadata to jwt-v0 and x-engflow-auth-token to the value of ENGFLOW_RPC_CREDENTIALS.
The token is issued with the same principal and roles as the requesting client, so the remote action can do the same things the user can. However, the token has a short lifetime, limited to the maximum action duration on the pool where the action is executed.