Skip to content

Commit

Permalink
Update GitLab claim mappings for build configs (#1206)
Browse files Browse the repository at this point in the history
* Update GitLab claim mappings for build configs

Assigns new `pipeline_ref/sha` claims to `Build Config` and
`Build Signer` related OIDs.

Depends on https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121597

Related to #1182

Signed-off-by: marshall007 <[email protected]>

* update docs to reflect GitLab claim mappings

Signed-off-by: marshall007 <[email protected]>

* updates to match new claim names

Signed-off-by: marshall007 <[email protected]>

* fix issuer test

Signed-off-by: marshall007 <[email protected]>

* address PR feedback

Signed-off-by: marshall007 <[email protected]>

* fix failing grpc server tests

Signed-off-by: marshall007 <[email protected]>

* fix lint error

Signed-off-by: marshall007 <[email protected]>

---------

Signed-off-by: marshall007 <[email protected]>
  • Loading branch information
marshall007 authored Jul 10, 2023
1 parent 07f0ac4 commit a4b3e12
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 38 deletions.
11 changes: 6 additions & 5 deletions docs/oid-info.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,19 +191,20 @@ that Sigstore operates.
| exp | exp | exp | exp | N/A | Only used to validate the JWT. |
| nbf | nbf | nbf | nbf | N/A | Only used to validate the JWT. Optional, as per the OIDC spec |
| iat | iat | iat | iat | N/A | Only used to validate the JWT. |
| server_url + job_workflow_ref | server_url + project_path + /-/jobs/ + job_id | ?? | ?? | Build Signer URI | Reference to specific build instructions that are responsible for signing. Can be the same as Build Config URI. For example a reusable workflow in GitHub Actions or a Circle CI Orbs. |
| job_workflow_sha | N/A | ?? | ?? | Build Signer Digest | An immutable reference to the specific version of the build instructions that is responsible for signing. Should include the digest type followed by the digest, e.g. `sha1:abc123`. |
| server_url + job_workflow_ref | ci_config_ref_uri ([WIP][gitlab-wip-cliams]) | ?? | ?? | Build Signer URI | Reference to specific build instructions that are responsible for signing. Can be the same as Build Config URI. For example a reusable workflow in GitHub Actions or a Circle CI Orbs. |
| job_workflow_sha | ci_config_sha ([WIP][gitlab-wip-cliams]) | ?? | ?? | Build Signer Digest | An immutable reference to the specific version of the build instructions that is responsible for signing. Should include the digest type followed by the digest, e.g. `sha1:abc123`. |
| runner_environment | runner_environment | ?? | ?? | Runner Environment | For platforms to specify whether the build took place in platform-hosted cloud infrastructure or customer-hosted infrastructure. For example: `platform-hosted` and `self-hosted`. |
| server_url + repository | server_url + project_path | ?? | ?? | Source Repository URI | Should include a fully qualified repository URL. |
| sha | sha | ?? | build_commit | Source Repository Digest | An immutable reference to a specific version of the source code. Should include the digest type followed by the digest, e.g. `sha1:abc123`. |
| ref | ref | ?? | build_branch | Source Repository Ref | The source ref that the build run was based upon. For example: refs/head/main. |
| repository_id | project_id | ?? | ?? | Source Repository Identifier | Stable identifier for the owner of the source repository. |
| server_url + repository_owner | server_url + namespace_path | ?? | ?? | Source Repository Owner URI | Fully qualified URL for the owner of the source repository. |
| repository_owner_id | namespace_id | ?? | ?? | Source Repository Owner Identifier | Stable identifier for the owner of the source repository. |
| server_url + workflow_ref | pipeline_ref ([WIP](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/117923)) | ?? | ?? | Build Config URI | A reference to the initiating build instructions. |
| workflow_sha | pipeline_sha ([WIP](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/117923)) | ?? | ?? | Build Config Digest | An immutable reference to the specific version of the top-level build instructions. Should include the digest type followed by the digest, e.g. `sha1:abc123`. |
| server_url + workflow_ref | ci_config_ref_uri ([WIP][gitlab-wip-cliams]) | ?? | ?? | Build Config URI | A reference to the initiating build instructions. |
| workflow_sha | ci_config_sha ([WIP][gitlab-wip-cliams]) | ?? | ?? | Build Config Digest | An immutable reference to the specific version of the top-level build instructions. Should include the digest type followed by the digest, e.g. `sha1:abc123`. |
| event_name | pipeline_source | ?? | ?? | Build Trigger | The event or action that triggered the build. |
| server_url + repository + "/actions/runs/" + run_id + "/attempts/" + run_attempt | server_url + project_path + /-/pipelines/ + pipeline_id | ?? | ?? | Run Invocation URI | An immutable identifier that can uniquely identify the build execution |
| server_url + repository + "/actions/runs/" + run_id + "/attempts/" + run_attempt | server_url + project_path + /-/jobs/ + job_id | ?? | ?? | Run Invocation URI | An immutable identifier that can uniquely identify the build execution |

[github-oidc-doc]: https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token
[oid-link]: http://oid-info.com/get/1.3.6.1.4.1.57264
[gitlab-wip-cliams]: https://gitlab.com/gitlab-org/gitlab/-/issues/404722
1 change: 1 addition & 0 deletions pkg/identity/gitlabcom/issuer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func TestIssuer(t *testing.T) {
"user_email": "[email protected]",
"pipeline_id": "757451528",
"pipeline_source": "push",
"ci_config_ref_uri": "gitlab.com/cpanto/testing-cosign//.gitlab-ci.yml@refs/head/main",
"job_id": "3659681386",
"sha": "714a629c0b401fdce83e847fc9589983fc6f46bc",
"runner_id": 1,
Expand Down
38 changes: 35 additions & 3 deletions pkg/identity/gitlabcom/principal.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ type jobPrincipal struct {
// Pipeline ID
pipelineID string

// Ref of top-level pipeline definition. E.g. gitlab.com/my-group/my-project//.gitlab-ci.yml@refs/heads/main
ciConfigRefURI string

// Commit sha of top-level pipeline definition, and is
// only populated when `ciConfigRefURI` is local to the GitLab instance
ciConfigSha string

// Repository building built
repository string

Expand Down Expand Up @@ -78,6 +85,8 @@ func JobPrincipalFromIDToken(_ context.Context, token *oidc.IDToken) (identity.P
ProjectID string `json:"project_id"`
PipelineSource string `json:"pipeline_source"`
PipelineID string `json:"pipeline_id"`
CiConfigRefURI string `json:"ci_config_ref_uri"`
CiConfigSha string `json:"ci_config_sha"`
NamespacePath string `json:"namespace_path"`
NamespaceID string `json:"namespace_id"`
JobID string `json:"job_id"`
Expand All @@ -104,6 +113,10 @@ func JobPrincipalFromIDToken(_ context.Context, token *oidc.IDToken) (identity.P
return nil, errors.New("missing pipeline_id claim in ID token")
}

if claims.CiConfigRefURI == "" {
return nil, errors.New("missing ci_config_ref_uri claim in ID token")
}

if claims.JobID == "" {
return nil, errors.New("missing job_id claim in ID token")
}
Expand Down Expand Up @@ -156,6 +169,8 @@ func JobPrincipalFromIDToken(_ context.Context, token *oidc.IDToken) (identity.P
url: `https://gitlab.com/`,
eventName: claims.PipelineSource,
pipelineID: claims.PipelineID,
ciConfigRefURI: claims.CiConfigRefURI,
ciConfigSha: claims.CiConfigSha,
repository: claims.ProjectPath,
ref: ref,
repositoryID: claims.ProjectID,
Expand All @@ -178,13 +193,30 @@ func (p jobPrincipal) Embed(_ context.Context, cert *x509.Certificate) error {
return err
}

// ci_config_ref_uri claim is a URI that does not include protocol scheme so we need to normalize it
ciConfigRefURL, err := url.Parse(p.ciConfigRefURI)
if err != nil {
return err
}

// default to https
ciConfigRefURL.Scheme = "https"

// or use scheme from issuer if from the same host
if baseURL.Host == ciConfigRefURL.Host {
ciConfigRefURL.Scheme = baseURL.Scheme
}

// Set workflow ref URL to SubjectAlternativeName on certificate
cert.URIs = []*url.URL{baseURL.JoinPath(fmt.Sprintf("%s@%s", p.repository, p.ref))}
cert.URIs = []*url.URL{ciConfigRefURL}

// Embed additional information into custom extensions
cert.ExtraExtensions, err = certificate.Extensions{
Issuer: p.issuer,
BuildSignerURI: baseURL.JoinPath(p.repository, "/-/jobs/", p.jobID).String(),
BuildConfigURI: ciConfigRefURL.String(),
BuildConfigDigest: p.ciConfigSha,
BuildSignerURI: ciConfigRefURL.String(),
BuildSignerDigest: p.ciConfigSha,
RunnerEnvironment: p.runnerEnvironment,
SourceRepositoryURI: baseURL.JoinPath(p.repository).String(),
SourceRepositoryDigest: p.sha,
Expand All @@ -193,7 +225,7 @@ func (p jobPrincipal) Embed(_ context.Context, cert *x509.Certificate) error {
SourceRepositoryOwnerURI: baseURL.JoinPath(p.repositoryOwner).String(),
SourceRepositoryOwnerIdentifier: p.repositoryOwnerID,
BuildTrigger: p.eventName,
RunInvocationURI: baseURL.JoinPath(p.repository, "/-/pipelines/", p.pipelineID).String(),
RunInvocationURI: baseURL.JoinPath(p.repository, "/-/jobs/", p.jobID).String(),
}.Render()
if err != nil {
return err
Expand Down
Loading

0 comments on commit a4b3e12

Please sign in to comment.