Authorization
BuildGrid supports authorization using JWTs, request headers, or an external Auth server. 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.
ACL configuration
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
- ...
actor, subject, and 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. For instances
in allow-unauthenticated-instances, these keys are ignored.
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
Localhost requests
The allow-localhost-requests configuration option can be used with any
authorization mode to allow requests originating from localhost to bypass
authentication requirements. This option accepts requests from:
IPv4 localhost (127.0.0.1)
IPv6 localhost (::1)
IPv4-mapped IPv6 localhost (::ffff:127.0.0.1)
Unix domain sockets
Abstract Unix domain sockets
When enabled, localhost requests skip identity verification but are still
subject to ACL authorization rules. This means ACL configurations must still
grant permission for the specific request types. The option defaults to
false for security.
This feature is useful for local development, administrative tools, or BuildGrid components that need to communicate with the server locally without requiring authentication setup.
Header-based authorization
authorization:
mode: headers
acls: /path/to/acl.yaml
allow-unauthenticated-instances: [ '', 'dev' ]
allow-localhost-requests: false
This authorization method reads the x-request-actor, x-request-subject,
and 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
allow-unauthenticated-instances: [ '', 'dev' ]
allow-localhost-requests: false
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 act, sub, and aud JWT
claims are compared with the actor, subject, and workflow regular expressions
respectively for the given instance to determine whether or not the request
is permitted.
If no ACL configuration is provided, then this authorization mode only ensures that the JWT is valid and not expired.
If you want to allow some instances to skip the authentication but still check against an ACL configuration you can optionally add your instances in allow-unauthenticated-instances.
JWKS-based JWT authorization
authorization:
mode: jwt
algorithm: hs256
jwks-url: http://example.com/jwks
jwks-fetch-minutes: 30
acls: /path/to/acl.yaml
allow-unauthenticated-instances: [ '', 'dev' ]
allow-localhost-requests: false
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 jwks-url.
The JWKS will be cached locally for jwks-fetch-minutes minutes, which
defaults to 60 if unset.
ACLs and unauthenticated instances are handled in exactly the same was as in the secret-based JWT approach.
Server-based authorization
authorization:
method: server
url: unix:///run/buildgrid/auth.sock
request-timeout: 5
acl-config: /path/to/acl.yaml
allow-unauthenticated-instances: [ '', 'dev' ]
allow-localhost-requests: false
Server-based authorization delegates authentication and authorization to an
external Auth server. For each request, BuildGrid reads the token from the
Authorization request header and calls the Auth server’s Authorize
method with the token, the instance name, and the full name of the gRPC method
being called. The Auth server either returns the client’s identity, or rejects
the request as unauthenticated or permission denied.
url is the address of the Auth server. request-timeout is the timeout
in seconds for each call to the Auth server, which defaults to 5.
The Auth server makes all authorization decisions for authenticated requests,
so the ACL configuration given by acl-config only applies to requests which
bypass authentication, through allow-unauthenticated-instances or
allow-localhost-requests.
Reference Auth server
BuildGrid includes a reference implementation of the Auth server, configured
with the !auth-service tag. It accepts the same keys as the JWT
authorization methods, apart from the bypasses, which the BuildGrid server
applies itself. It is usually run in its own BuildGrid process listening on a
unix socket.
server:
- !channel
address: unix:///run/buildgrid/auth.sock
insecure-mode: true
services:
- !auth-service
algorithm: rs256
jwks-url: https://example.com/.well-known/jwks.json
audience: BuildGrid
acl-config: /path/to/acl.yaml
The JWT is validated in the same way as in the JWT authorization methods, and the resulting identity is checked against the ACL configuration.