BuildGrid supports authorization using either JWTs or request headers. When using request headers, the authenticity of the claimed identity is not verifiable by BuildGrid. This means that the headers should be set by (for example) a trusted proxy which does some identity verification rather than the client directly.
Controlling access to individual requests is done by configuring an ACL. This configuration is optional, but if present must completely define access to all instances specified in the main configuration file. Missing instances default to denying all access.
Regardless of the authorization mode, the
acls configuration key can
be used to provide the path to an ACL configuration file.
The config is of the format:
<instance-name>: allow: - actor: .* subject: .* workflow: .* requests: # List of request name strings - Execute - ...
workflow are optional keys which allow limiting
access based on the client’s identity. These keys are regular expressions used
to match against the identity information provided by the client.
There can be multiple entries in this
allow list, if different client
identities need to be able to have different access permissions.
If an ACL configuration file is provided, then all instance names in the main config file must have a corresponding entry defined in the ACL configuration file. Any missing instance names will have all requests denied by default. To ease verbosity if not all instance names actually need authorization, there is a shorthand for “allow all”.
<instance-name>: allow: all
An exhaustive example could be as follows.
prod: allow: # All prod user accounts have CAS write access - actor: prod.* requests: - BatchUpdateBlobs - QueryWriteStatus - Write # Only requests with the correct actor claim can perform read/write # requests - actor: prodbuilder requests: - Execute - WaitExecution - CancelOperation # Only workers should be able to connect to the Bots service - actor: prodworker requests: - CreateBotSession - UpdateBotSession # BuildGrid itself needs to be able to create LogStreams and # update ActionResults - actor: bgd requests: - CreateLogStream - UpdateActionResult # Read-only requests should be allowed regardless of header claims - requests: - GetCapabilities - GetActionResult - GetOperation - ListOperations - Read - FindMissingBlobs - BatchReadBlobs - GetTree
authorization: mode: headers acls: /path/to/acl.yaml
This authorization method reads the
x-request-workflow headers and compares them with the corresponding
regular expressions defined in the ACL configuration.
If no ACL is configured then this method does no authorization, and all requests are permitted.
Since there is no way to verify the authenticity of these headers, it is important to only use this method when the requests are from a trusted source. A deployment architecture where this may be useful is deploying BuildGrid strictly behind a reverse proxy, where the reverse proxy is responsible for validating the client identity and setting these headers before forwarding the request.
Secret-based JWT authorization
authorization: mode: jwt algorithm: hs256 secret: /path/to/secret.key acl-config: /path/to/acl.yaml
Secret-based JWT authorization expects incoming requests to populate the
Authorization request header with a JWT containing some claims about
the client identity. The JWT must be able to be decoded using the given
secret and algorithm.
If an ACL configuration is provided, the
claims are compared with the actor, subject, and workflow regular expressions
respectively for the given instance to determine whether or not the request
If no ACL configuration is provided, then this authorization mode only ensures that the JWT is valid and not expired.
JWKS-based JWT authorization
authorization: mode: jwt algorithm: hs256 jwks-url: http://example.com/jwks jwks-fetch-minutes: 30 acls: /path/to/acl.yaml
JWKS-based JWT authorization works in the same way as the secret-based JWT
approach, except the secret key(s) for decoding JWTs are fetched from a remote
server as a JWKS. For a JWT to be valid it must be able to be decoded with
one of the keys in the key set returned from the given
The JWKS will be cached locally for
jwks-fetch-minutes minutes, which
defaults to 60 if unset.
ACLs are handled in exactly the same was as in the secret-based JWT approach.