diff --git a/pages/agent/v3/cli_oidc.md b/pages/agent/v3/cli_oidc.md index aef2b3ae4d..cfe74b0c46 100644 --- a/pages/agent/v3/cli_oidc.md +++ b/pages/agent/v3/cli_oidc.md @@ -24,6 +24,8 @@ For specific endpoints for OpenID or JWKS, use: ## Claims +All of the following claims (with the exception of the [`aud` claim](#aud), which is usually overridden by the [`--audience` option](#audience)) are automatically generated by the Buildkite Agent, and are based on metadata from the pipeline job it is currently building. + @@ -53,7 +55,7 @@ For specific endpoints for OpenID or JWKS, use:

Example:organization:acme-inc:pipeline:super-duper-app:ref:refs/heads/main:commit:9f3182061f1e2cca4702c368cbc039b7dc9d4485:step:build

- + - + - + - + - + - + - + +
aud

Audience

@@ -63,7 +65,7 @@ For specific endpoints for OpenID or JWKS, use: --audience flag

exp

Expiration time

@@ -73,7 +75,7 @@ For specific endpoints for OpenID or JWKS, use:

Example: 1669015898

nbf

Not before

@@ -82,7 +84,7 @@ For specific endpoints for OpenID or JWKS, use:

Example: 1669014898

iat

Issued at

@@ -91,14 +93,14 @@ For specific endpoints for OpenID or JWKS, use:

Example: 1669014898

organization_slug

The organization's slug.

Example: acme-inc

pipeline_slug

The pipeline's slug.

@@ -112,7 +114,7 @@ For specific endpoints for OpenID or JWKS, use:

Example: 1

build_branch

The repository branch used in the build.

@@ -161,7 +163,21 @@ For specific endpoints for OpenID or JWKS, use: ### Optional claims -Generate these additional claims by adding `--claims` to the `buildkite-agent oidc request-token` command. +You can generate additional optional claims by adding `--claims` to the `buildkite-agent oidc request-token` command. The `--claims` option can also take multiple values. + +For example, this command adds the Buildkite organization's UUID value as a claim to the OIDC token: + +```sh +$ buildkite-agent oidc request-token ... --claim "organization_id" +``` + +This command adds both the Buildkite organization's UUID and pipeline's UUID values in their own additional claims to the OIDC token: + +```sh +$ buildkite-agent oidc request-token ... --claim "organization_id,pipeline_id" +``` + +The following optional claims can be added, whose values are automatically generated by the Buildkite Agent, and are based on the pipeline job it is currently building. diff --git a/pages/apis/rest_api/packages/registries.md b/pages/apis/rest_api/packages/registries.md index 2a604a7a0e..10d4978044 100644 --- a/pages/apis/rest_api/packages/registries.md +++ b/pages/apis/rest_api/packages/registries.md @@ -11,8 +11,19 @@ curl -H "Authorization: Bearer $TOKEN" \ -d '{ "name": "my registry", "ecosystem": "ruby", - "description": "registry containing ruby gems" - }' + "description": "registry containing ruby gems", + "oidc_policy": [ + { + "iss": "https://agent.buildkite.com", + "claims": { + "organization_slug": "my-org", + "pipeline_slug": { + "in": ["my-pipeline", "my-other-pipeline"] + } + } + } + ] + }' ``` ```json @@ -46,6 +57,7 @@ Optional [request body properties](/docs/api#request-body-properties):
+
descriptionDescription of the registry.
Default value: null.
oidc_policyA policy matching a basic or more complex OIDC policy format. Can be either stringified YAML, or a JSON array of policy statements.
Default value: null.
@@ -123,8 +135,19 @@ curl -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "my registry", - "description": "registry containing ruby gems" - }' + "description": "registry containing ruby gems", + "oidc_policy": [ + { + "iss": "https://agent.buildkite.com", + "claims": { + "organization_slug": "my-org", + "pipeline_slug": { + "in": ["my-pipeline"] + } + } + } + ] + }' ``` ```json @@ -150,6 +173,7 @@ Optional [request body properties](/docs/api#request-body-properties):
nameName of the registry.
Example: my registry.
descriptionDescription of the registry.
Example: registry containing ruby gems.
oidc_policyA policy matching a basic or more complex OIDC policy format. Can be either stringified YAML, or a JSON array of policy statements. Be aware that if you are modifying an existing OIDC policy, the entire revised OIDC policy needs to be re-posted in this update request.
Default value: null.
diff --git a/pages/packages/permissions.md b/pages/packages/permissions.md index 91ecdb1b28..3249b85d4a 100644 --- a/pages/packages/permissions.md +++ b/pages/packages/permissions.md @@ -96,8 +96,4 @@ From this page, you can configure the following permissions for all users across ## Manage an agent's access to registries -To configure the rules by which a Buildkite Agent can access a registry, you'll need to configure the OpenID Connect (OIDC) policy within the registry to allow the Buildkite Agent to request an OIDC token (using the [`buildkite-agent oidc request-token`](/docs/agent/v3/cli-oidc#request-oidc-token) command). - - +To configure the rules by which a Buildkite Agent can access a registry, you'll need to configure the [OpenID Connect (OIDC) policy](/docs/packages/security/oidc) within the registry to allow the Buildkite Agent to request an OIDC token (using the [`buildkite-agent oidc request-token`](/docs/agent/v3/cli-oidc#request-oidc-token) command). diff --git a/pages/packages/security/oidc.md b/pages/packages/security/oidc.md index 7cb66fbbe4..8eba6c91d3 100644 --- a/pages/packages/security/oidc.md +++ b/pages/packages/security/oidc.md @@ -2,18 +2,32 @@ <%= render_markdown partial: 'platform/oidc_introduction' %> -You can configure Buildkite Packages registries with OIDC policies that only permit Buildkite Agent interactions from specific Buildkite organizations, pipelines, jobs, and agents, associated with a pipeline's job. This is similar to how [third-party products and services can be configured with OIDC policies](/docs/pipelines/security/oidc) to consume Buildkite OIDC tokens from Buildkite pipelines, for deployment, or access management and security purposes. +You can configure registries in Buildkite Packages with OIDC policies that allow access using OIDC tokens issued by Buildkite Agents and other OIDC identity providers. This is similar to how [third-party products and services can be configured with OIDC policies](/docs/pipelines/security/oidc) to consume Buildkite Agent OIDC tokens for specific pipeline jobs, for deployment, or access management and security purposes. -A Buildkite OIDC token is a signed [JSON Web Token (JWT)](https://jwt.io/) provided by a Buildkite Agent, containing metadata claims about a pipeline and its job, including the pipeline and organization slugs, as well as job-specific data, such as the branch, the commit SHA, the job ID, and the agent ID. Such a token is associated with a Buildkite Agent interaction to perform one or more actions on a Buildkite Packages registry. If the token's claims do not match or comply with the registry's OIDC policy, the OIDC token and subsequent pipeline jobs' actions are rejected. +A Buildkite Agent's OIDC tokens assert claims about the slugs of the pipeline it is building and organization that contains this pipeline, the ID of the job that created the token, as well as other claims, such as the name of the branch used in the build, the SHA of the commit that triggered the build, and the agent ID. If the token's claims do not comply with the registry's OIDC policy, the OIDC token is rejected, and any actions attempted with that token will fail. If the claims do comply, however, the OIDC token will have read and write access to packages in the registry. -The [Buildkite Agent's `oidc` command](/docs/agent/v3/cli-oidc) allows you to request an OIDC token from Buildkite containing claims about the pipeline's current job. These tokens are then used by a Buildkite Packages registry to determine (through its OIDC policy) if the organization, pipeline and any other metadata associated with the pipeline and its job are permitted to publish/upload packages to this registry. +The [Buildkite Agent's `oidc` command](/docs/agent/v3/cli-oidc) allows you to request an OIDC token from Buildkite containing claims about the pipeline's current job. These tokens can then be used by a registry in Buildkite Packages to determine (through its OIDC policy) if the organization, pipeline and any other metadata associated with the pipeline and its job are permitted to publish/upload packages to this registry. -> 📘 -> Buildkite Packages registries also support OIDC policies that can consume OIDC tokens configured on third-party products and services, such as [GitHub Actions](https://github.com/features/actions), to authenticate interactions from these services. +## OIDC token requirements + +All registries in Buildkite Packages defined with an OIDC policy, require the following claims from an OIDC token (unless indicated as optional), regardless of the OIDC identity provider that issued the token. + +| Claim | Value | +| ----- | ----- | +| [`iat` (issued at)](/docs/agent/v3/cli-oidc#iat) | Must be a UNIX timestamp in the past. | +| [`nbf` (not before)](/docs/agent/v3/cli-oidc#nbf) (Optional) | If present, must be a UNIX timestamp in the past. | +| [`exp` (expiration time)](/docs/agent/v3/cli-oidc#exp) | Must be a UNIX timestamp in the future. The OIDC token's lifespan—that is, the `exp` minus the `iat` timestamp values—cannot be greater than 5 minutes. | +| [`aud` (audience)](/docs/agent/v3/cli-oidc#aud) | Must be equal to the registry's canonical URL, which has the format `https://packages.buildkite.com/{org.slug}/{registry.slug}`. | + +When generating an OIDC token from: + +- A [Buildkite Agent](/docs/agent/v3/cli-oidc), the [`--audience` option](/docs/agent/v3/cli-oidc#audience) must explicitly be specified with the required value, whereas `iat`, `nbf` and `exp` claims will automatically be included in the token. + +- Another OIDC identity provider, ensure that its OIDC tokens contain these required claims. This should be the case by default, but if not, consult the relevant documentation for your OIDC identity provider on how to include these claims in the OIDC tokens it issues. ## Define an OIDC policy for a registry -You can specify an OIDC policy for your Buildkite registry, which defines the criteria for which OIDC tokens, from the [Buildkite Agent](/docs/agent/v3/cli-oidc) or another third-party system, will be accepted by your registry and authenticate a package publication/upload action from that system. +You can specify an OIDC policy for your Buildkite registry, which defines the criteria for which OIDC tokens, from the [Buildkite Agent](/docs/agent/v3/cli-oidc) or another OIDC identity provider, will be accepted by your registry and authenticate a package publication/upload action from that system. To define an OIDC policy for one or more Buildkite pipeline jobs in a registry: @@ -23,48 +37,145 @@ To define an OIDC policy for one or more Buildkite pipeline jobs in a registry: 1. Select **Settings** > **OIDC Policy** to access the registry's **OIDC Policy** page. -1. In the **Policy** field, specify this using the following format: +1. In the **Policy** field, specify this using the following [Basic OIDC policy format](#define-an-oidc-policy-for-a-registry-basic-oidc-policy-format), or one based on a more [complex example](#define-an-oidc-policy-for-a-registry-complex-oidc-policy-example). + +Learn more about how an OIDC policy for a registry is constructed in [Policy structure and behavior](#define-an-oidc-policy-for-a-registry-policy-structure-and-behavior). - ```yaml - - iss: https://agent.buildkite.com - organization_slug: organization-slug - pipeline_slug: pipeline-slug - build_branch: main - ``` +### Basic OIDC policy format - where: - * `iss` (the issuer) must be `https://agent.buildkite.com`, representing the Buildkite Agent. - * `organization-slug` can be obtained from the end of your Buildkite URL, after accessing **Packages** or **Pipelines** in the global navigation of your organization in Buildkite. - * `pipeline-slug` can be obtained from the end of your Buildkite URL, after accessing **Pipelines** in the global navigation of your organization in Buildkite. - * `main` or whichever branch of the repository you want to restrict package publication/uploads from pipeline builds. +The basic format for an OIDC policy for OIDC tokens issued by a Buildkite Agent is: -Each of these OIDC policy fields acts as a _filter_ and only authenticates and accepts OIDC tokens from Buildkite Agent pipelines and jobs whose criteria match these field values. Therefore, omitting a field makes the policy less strict. +```yaml +- iss: https://agent.buildkite.com + claims: + organization_slug: organization-slug + pipeline_slug: pipeline-slug + build_branch: main +``` + +where: -You can also specify multiple _rules_ in this **Policy** field to allow your registry to accept jobs from other pipelines, as well as OIDC tokens from other systems. +- `iss` (the issuer) must be `https://agent.buildkite.com`, representing the Buildkite Agent. +- `organization-slug` can be obtained from the end of your Buildkite URL, after accessing **Packages** or **Pipelines** in the global navigation of your organization in Buildkite. +- `pipeline-slug` can be obtained from the end of your Buildkite URL, after accessing **Pipelines** in the global navigation of your organization in Buildkite. +- `main` or whichever branch of the repository you want to restrict package publication/uploads from pipeline builds. -### Example OIDC policy for a registry +However, more [complex OIDC policies](#define-an-oidc-policy-for-a-registry-complex-oidc-policy-example) can be created. -The following example OIDC policy defined on a registry (with two rules): +### Complex OIDC policy example + +The following OIDC policy for a registry in Buildkite Packages contains two [_statements_](#statements)—one for a registry in Buildkite Packages and another for GitHub Actions. ```yaml - iss: https://agent.buildkite.com - organization_slug: my-organization - pipeline_slug: my-pipeline - build_branch: main + claims: + organization_slug: + equals: your-org + pipeline_slug: + in: + - one-pipeline + - another-pipeline + build_branch: + matches: + - main + - feature/* + not_equals: feature/not-this-one + +- iss: https://token.actions.githubusercontent.com + claims: + repository: + matches: your-org/* + actor: + in: + - deploy-bot + - revert-bot +``` + +The first statement allows OIDC tokens representing a pipeline's job being built by a Buildkite Agent, but only when all of the following is true for the tokens' claims: + +- The [organization slug](/docs/agent/v3/cli-oidc#organization-slug) is `your-org` +- The [pipeline slug](/docs/agent/v3/cli-oidc#pipeline-slug) is either `one-pipeline` or `another-pipeline` +- The [build branch](/docs/agent/v3/cli-oidc#build-branch) is either `main` or matches a `feature/*` branch + +The second statement allows OIDC tokens representing a GitHub Actions workflow, but only when all of the following is true for the tokens' claims: + +- The repositories match `your-org/*` +- The actor is either `deploy-bot` or `revert-bot` + +### Policy structure and behavior + +OIDC policy [_statements_](#statements) in Buildkite Packages are defined as a YAML- or JSON-formatted list, each of which includes a _token issuer_ from an OIDC identity provider, along with a map of [_claim rules_](#claim-rules). + +If an OIDC token's claims match both the token issuer and _all_ claim rules defined by any statement within a registry's OIDC policy, then the token is accepted and the OIDC identity provider that issued the token is granted access to the registry. If no statements of the OIDC policy match, the token is rejected, and no registry access is granted. + +When using YAML to define an OIDC policy, only _simple_ YAML syntax is accepted—that is, YAML containing only scalar values, maps, and lists. Complex YAML syntax and features, such as anchors, aliases, and tagged values are not supported. + + + +#### Statements + +A _statement_ defines a list of [_claim rules_](#claim-rules) for a particular _token issuer_ within an OIDC policy, where a token issuer is typically determined by an OIDC identity provider. + +Each statement in the policy must contain contain a token issuer (`iss`) field, whose value is determined by the OIDC identity provider, and permits OIDC tokens from that token issuer. While multiple statements are typically used to allow access from multiple token issuers (that is, one statement per issuer), more than one statement can also be defined for a single issuer or OIDC identity provider to handle more complex claim rule scenarios. + +A statement must also contain a `claims` field, which is a map of [claim rules](#claim-rules). + +Currently, only OIDC tokens from the following token issuers are supported. + +| Token issuer name | The token issuer (`iss`) value | Relevant documentation link | +| ----------------- | ------------------------------ | --------------------------- | +| Buildkite | `https://agent.buildkite.com` | [Buildkite Agent `oidc` command](/docs/agent/v3/cli-oidc) | +| GitHub Actions | `https://token.actions.githubusercontent.com` | [GitHub Actions OIDC Tokens](https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/about-security-hardening-with-openid-connect) | +| CircleCI | `https://oidc.circleci.com/org/$ORG` where `$ORG` is your organization name | [CircleCI OIDC Tokens](https://circleci.com/docs/openid-connect-tokens) | + +If you'd like to use OIDC tokens from a different token issuer or OIDC identity provider in Buildkite Packages, please contact [support](https://buildkite.com/support). + + + +#### Claim rules + +A [_statement_](#statements) contains a `claims` field, which in turn contains a map of _claim rules_, where the rule's key is the name of the claim being verified, and the rule's value is the actual rule used to verify this claim. Each rule is a map of [_matchers_](#claim-rule-matchers), which are used to match a claim value in an OIDC token. + +If at least one claim rule defined within an OIDC policy's statement is missing from an OIDC token and no other statements in that policy have complete matches with the token's claims, then the token is rejected. When a claim rule contains multiple matchers—such as the `build_branch` claim rule in the [complex example](#define-an-oidc-policy-for-a-registry-complex-oidc-policy-example) above—_all_ of the rule's matchers must match a claim in the token for it to be granted registry access. In the `build_branch` example above, this means that the token must have a `build_branch` claim whose value is either `main` or begins with `feature/`, but whose value is not `feature/not-this-one`. + +Be aware that this means some combinations of matchers used in a claim rule may never match an OIDC token's claims. For example, the following OIDC policy statement will always reject a token, since the token's `build_branch` claim cannot be both equal to `main` and not equal to `main` at the same time: + +```yaml - iss: https://agent.buildkite.com - organization_slug: my-organization - pipeline_slug: my-second-pipeline + claims: + build_branch: + equals: main + not_equals: main ``` -Will only authenticate and accept OIDC tokens (and therefore, allow package publishing/uploads to this registry) from Buildkite Agents: + + +#### Claim rule matchers -- Configured with the Buildkite organization `my-organization`. +The following _matchers_ can be used within a [_claim rule_](#claim-rules). -- Running pipeline builds of the `my-pipeline` or `my-second-pipeline` pipelines within this organization. +| Matcher | Argument type | Description | +| ------- | ------------- | ----------- | +| `equals` | Scalar | The claim value must be exactly equal to the argument. | +| `not_equals` | Scalar | The claim value must not be exactly equal to the argument. | +| `in` | List of scalars | The claim value must be in the list of arguments. | +| `not_in` | List of scalars | The claim value must not be in the list of arguments. | +| `matches` | List of glob strings OR a single glob string | The claim value must match at least one of the globs provided. Note that this matcher is only applied when the claim value is a string, and is ignored otherwise. | -- For `my-pipeline`, running builds from the `main` branch of the repository. +Argument type details: -- For `my-second-pipeline`, running builds from any branch of the repository. +- A scalar is a single value, which must be a String, Number (float or integer), Boolean, or Null. + +- A glob string is a string that may contain wildcards, such as `*` or `?`, which match zero or more characters, or a single character respectively. Glob strings are _not_ regular expressions, and do not support the full range of features that regular expressions do. + +As a special case, if a claim rule in its entirety is a scalar, it is treated as if it were a rule with the `equals` matcher. This means that the following two claim rules are equivalent: + +```yaml +organization_slug: your-org +# is equivalent to +organization_slug: + equals: your-org +``` ## Configure a Buildkite pipeline to authenticate to a registry diff --git a/pages/pipelines/security/oidc.md b/pages/pipelines/security/oidc.md index 9c0ead14e9..8f2764ca32 100644 --- a/pages/pipelines/security/oidc.md +++ b/pages/pipelines/security/oidc.md @@ -6,10 +6,10 @@ keywords: oidc, authentication, IAM, roles <%= render_markdown partial: 'platform/oidc_introduction' %> -You can configure third-party products and services, such as [AWS](https://aws.amazon.com/), [GCP](https://cloud.google.com/), [Azure](https://azure.microsoft.com/) and many others, as well as Buildkite products, such as [Packages](/docs/packages/security/oidc), with OIDC policies that only permit Buildkite Agent interactions from specific Buildkite organizations, pipelines, jobs, and agents, associated with a pipeline's job. +You can configure third-party products and services, such as [AWS](https://aws.amazon.com/), [GCP](https://cloud.google.com/), [Azure](https://azure.microsoft.com/) and many others, as well as Buildkite products, such as [Packages](/docs/packages/security/oidc), with OIDC policies that only permit Buildkite Agent interactions from specific Buildkite organizations, pipelines, agents, and other metadata associated with the pipeline's job. -A Buildkite OIDC token is a signed [JSON Web Token (JWT)](https://jwt.io/) provided by a Buildkite Agent, containing metadata claims about a pipeline and its job, including the pipeline and organization slugs, as well as job-specific data, such as the branch, the commit SHA, the job ID, and the agent ID. Such a token is associated with a Buildkite Agent interaction to perform one or more actions within the third-party service. If the token's claims do not match or comply with the service's OIDC policy, the OIDC token and subsequent pipeline jobs' interactions are rejected. +A Buildkite OIDC token can be issued by a Buildkite Agent, asserting claims about the slugs of the pipeline it is building and organization that contains this pipeline, the ID of the job that created the token, as well as other claims, such as the name of the branch used in the build, the SHA of the commit that triggered the build, and the agent ID. Such a token is associated with a Buildkite Agent interaction to perform one or more actions within the third-party service. If the token's claims do not comply with the service's OIDC policy, the token is rejected and subsequent pipeline jobs' interactions are rejected. -The [Buildkite Agent's `oidc` command](/docs/agent/v3/cli-oidc) allows you to request an OIDC token from Buildkite containing claims about the pipeline's current job. These tokens are then consumed by federated systems like AWS, and exchanged for authenticated role-based access with specific permissions to interact with your cloud environments. +The [Buildkite Agent's `oidc` command](/docs/agent/v3/cli-oidc) allows you to request an OIDC token from Buildkite containing claims about the pipeline's current job. These tokens can then be consumed by federated systems like AWS, and exchanged for authenticated role-based access with specific permissions to interact with your cloud environments. This section of the Buildkite Docs covers Buildkite's OIDC implementation with other federated systems, such as [AWS](/docs/pipelines/security/oidc/aws). diff --git a/pages/platform/_oidc_introduction.md b/pages/platform/_oidc_introduction.md index 720bb0d49c..ca1e2b7cd8 100644 --- a/pages/platform/_oidc_introduction.md +++ b/pages/platform/_oidc_introduction.md @@ -1 +1 @@ -[Open ID Connect (OIDC)](https://openid.net/developers/how-connect-works/) is an authentication protocol based on the [OAuth 2.0 framework](https://auth0.com/docs/authenticate/protocols/oauth/). With OIDC, one system or service issues an _OIDC token_ containing signed metadata (or _claims_) about a user or object. This token can be consumed by another service (which may be offered by a third-party or by the same organization) to authenticate the user or object. An _OIDC policy_ configured on this other service defines which OIDC tokens (based on their claims) are permitted to perform the actions. If the OIDC token's claims match those of the OIDC policy configured in the other service, the token is authenticated and the service issuing the token is permitted to perform its actions on the other service. +[Open ID Connect (OIDC)](https://openid.net/developers/how-connect-works/) is an authentication protocol based on the [OAuth 2.0 framework](https://auth0.com/docs/authenticate/protocols/oauth/). With OIDC, one system or service issues an _OIDC token_, which is a signed [JSON Web Token (JWT)](https://jwt.io/) containing metadata (or _claims_) about a user or object. This token can be consumed by another service (which may be offered by a third-party or by the same organization) to authenticate the user or object. An _OIDC policy_ configured on this other service defines which OIDC tokens, based on their claims (also known as _asserted_ claims) are permitted to perform the actions. If the OIDC token's asserted claims comply with those of the OIDC policy configured in the other service, the token is authenticated and the service issuing the token is permitted to perform its actions on the other service. diff --git a/vale/styles/vocab.txt b/vale/styles/vocab.txt index 9d48ab082a..58544c5abf 100644 --- a/vale/styles/vocab.txt +++ b/vale/styles/vocab.txt @@ -122,6 +122,7 @@ LFS libpq linux macOS +matchers Memcache minitest misconfiguration @@ -195,6 +196,7 @@ sre sso statefully stdout +stringified subcommand subcommands subfolders