Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Codefresh OIDC provider #1593

Merged
merged 7 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions config/config.jsn
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
"IssuerURL": "https://token.actions.githubusercontent.com",
"ClientID": "sigstore",
"Type": "github-workflow"
},
"https://oidc.codefresh.io": {
"IssuerURL": "https://oidc.codefresh.io",
"ClientID": "sigstore",
"Type": "codefresh-workflow"
}
}
}
5 changes: 5 additions & 0 deletions config/fulcio-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ data:
"Type": "email",
"IssuerClaim": "$.federated_claims.connector_id"
},
"https://oidc.codefresh.io": {
"IssuerURL": "https://oidc.codefresh.io",
"ClientID": "sigstore",
"Type": "codefresh-workflow"
},
"https://ops.gitlab.net": {
"IssuerURL": "https://ops.gitlab.net",
"ClientID": "sigstore",
Expand Down
42 changes: 21 additions & 21 deletions docs/oid-info.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,27 +189,27 @@ that Sigstore operates.

## Mapping OIDC token claims to Fulcio OIDs

| GitHub [(docs)][github-oidc-doc] | GitLab [(docs)](https://docs.gitlab.com/ee/ci/secrets/id_token_authentication.html#token-payload) | CircleCI | Buildkite | Fulcio Certificate Extension | Why / Notes / Questions |
|--------------------|--------|----------|-----------|------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| aud | aud | aud | aud | N/A | Only used to validate the JWT. |
| iss | iss | iss | iss | Issuer | This already exists. For example: https://token.actions.githubusercontent.com |
| 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 | 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 | 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 + /-/jobs/ + job_id | ?? | ?? | Run Invocation URI | An immutable identifier that can uniquely identify the build execution |
| repository_visibility | project_visibility | ?? | ?? | Source Repository Visibility At Signing | Source repository visibility at the time of signing the certificate |
| GitHub [(docs)][github-oidc-doc] | GitLab [(docs)](https://docs.gitlab.com/ee/ci/secrets/id_token_authentication.html#token-payload) | CircleCI | Buildkite | Codefresh [(docs)](https://codefresh.io/docs/docs/integrations/oidc-pipelines/) | Fulcio Certificate Extension | Why / Notes / Questions |
|--------------------|--------|----------|-----------|-----------|------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| aud | aud | aud | aud | aud | N/A | Only used to validate the JWT. |
| iss | iss | iss | iss | iss | Issuer | This already exists. For example: https://token.actions.githubusercontent.com |
| exp | exp | exp | exp | exp | N/A | Only used to validate the JWT. |
| nbf | nbf | nbf | nbf | nbf | N/A | Only used to validate the JWT. Optional, as per the OIDC spec |
| iat | iat | iat | iat | iat | N/A | Only used to validate the JWT. |
| server_url + job_workflow_ref | ci_config_ref_uri ([WIP][gitlab-wip-cliams]) | ?? | ?? | platform_url + /build/ + workflow_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. |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just want to check that the URLs starting with platform_url in this file in this pull request are right - they aren't namespaces by account_name or pipeline_name or anything like that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, the urls are correct. Accounts in Codefresh are populated upon login (either through the UI or API tokens which are scoped to an account)

| job_workflow_sha | ci_config_sha ([WIP][gitlab-wip-cliams]) | ?? | ?? | 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`. |
| runner_environment | 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`. |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent! I'm glad to see you support this, as the security properties of platform-hosted of customer self-hosted instances can be quite different.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to check, this is supported currently? I didn't see it mentioned in the docs.

| server_url + repository | server_url + project_path | ?? | ?? | scm_repo_url | Source Repository URI | Should include a fully qualified repository URL. |
| sha | sha | ?? | build_commit | N/A | 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`. |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope for this PR, but an ask for Codefresh: it would be great if this could start to be captured in OIDC claims so that users can know what version of the pipeline config was used for the build.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your detailed review @wlynch! We will for sure discuss it internally and try to come up with a relevant claim.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this line actually refers to the SHA of the source code the pipeline pulls in (e.g. whatever https://codefresh.io/docs/docs/pipelines/steps/git-clone/ resolves, if I understand the documentation correctly). The isn't required generally, but is incredibly valuable in providing build provenance that not only points to the source repository but the specific SHA that the build used.

workflow_sha (or job_workflow_sha if the initial job calls another job to interact with Fulcio) would be the version of the pipeline config used by the build, and I agree that it is also very useful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@steiza We will for sure take it into account. I'll work with the relevant dev team to have a relevant claim added in the near future, and will add it as soon as it is available.

| ref | ref | ?? | build_branch | scm_ref | Source Repository Ref | The source ref that the build run was based upon. For example: refs/head/main. |
| repository_id | project_id | ?? | ?? | N/A | Source Repository Identifier | Stable identifier for the owner of the source repository. |
| server_url + repository_owner | server_url + namespace_path | ?? | ?? | N/A | Source Repository Owner URI | Fully qualified URL for the owner of the source repository. |
| repository_owner_id | namespace_id | ?? | ?? | N/A | Source Repository Owner Identifier | Stable identifier for the owner of the source repository. |
| server_url + workflow_ref | ci_config_ref_uri ([WIP][gitlab-wip-cliams]) | ?? | ?? | platform_url + /api/pipelines/ + pipeline_id | Build Config URI | A reference to the initiating build instructions. |
| workflow_sha | ci_config_sha ([WIP][gitlab-wip-cliams]) | ?? | ?? | N/A | 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 | ?? | ?? | N/A | Build Trigger | The event or action that triggered the build. |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not required, but could this potentially be populated by https://codefresh.io/docs/docs/pipelines/triggers/?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not supported at the moment but I will take it internally, maybe we can support it In the future. Will make sure to add this extension when we do.

| server_url + repository + "/actions/runs/" + run_id + "/attempts/" + run_attempt | server_url + project_path + /-/jobs/ + job_id | ?? | ?? | platform_url + /build/ + workflow_id | Run Invocation URI | An immutable identifier that can uniquely identify the build execution |
| repository_visibility | project_visibility | ?? | ?? | N/A | Source Repository Visibility At Signing | Source repository visibility at the time of signing the certificate |

[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
Expand Down
18 changes: 18 additions & 0 deletions federation/oidc.codefresh.io/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2023 The Sigstore Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

url: https://oidc.codefresh.io
contact: support@codefresh.io
description: "Codefresh OIDC tokens for job identity"
type: "codefresh-workflow"
19 changes: 11 additions & 8 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,14 +273,15 @@ func (fc *FulcioConfig) prepare() error {
type IssuerType string

const (
IssuerTypeBuildkiteJob = "buildkite-job"
IssuerTypeEmail = "email"
IssuerTypeGithubWorkflow = "github-workflow"
IssuerTypeGitLabPipeline = "gitlab-pipeline"
IssuerTypeKubernetes = "kubernetes"
IssuerTypeSpiffe = "spiffe"
IssuerTypeURI = "uri"
IssuerTypeUsername = "username"
IssuerTypeBuildkiteJob = "buildkite-job"
IssuerTypeEmail = "email"
IssuerTypeGithubWorkflow = "github-workflow"
IssuerTypeCodefreshWorkflow = "codefresh-workflow"
IssuerTypeGitLabPipeline = "gitlab-pipeline"
IssuerTypeKubernetes = "kubernetes"
IssuerTypeSpiffe = "spiffe"
IssuerTypeURI = "uri"
IssuerTypeUsername = "username"
)

func parseConfig(b []byte) (cfg *FulcioConfig, err error) {
Expand Down Expand Up @@ -511,6 +512,8 @@ func issuerToChallengeClaim(issType IssuerType, challengeClaim string) string {
return "email"
case IssuerTypeGithubWorkflow:
return "sub"
case IssuerTypeCodefreshWorkflow:
return "sub"
case IssuerTypeKubernetes:
return "sub"
case IssuerTypeSpiffe:
Expand Down
3 changes: 3 additions & 0 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,9 @@ func Test_issuerToChallengeClaim(t *testing.T) {
if claim := issuerToChallengeClaim(IssuerTypeGitLabPipeline, ""); claim != "sub" {
t.Fatalf("expected sub subject claim for GitLab issuer, got %s", claim)
}
if claim := issuerToChallengeClaim(IssuerTypeCodefreshWorkflow, ""); claim != "sub" {
t.Fatalf("expected sub subject claim for Codefresh issuer, got %s", claim)
}
if claim := issuerToChallengeClaim(IssuerTypeKubernetes, ""); claim != "sub" {
t.Fatalf("expected sub subject claim for K8S issuer, got %s", claim)
}
Expand Down
40 changes: 40 additions & 0 deletions pkg/identity/codefresh/issuer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2023 The Sigstore Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package codefresh

import (
"context"
"fmt"

"github.com/sigstore/fulcio/pkg/config"
"github.com/sigstore/fulcio/pkg/identity"
"github.com/sigstore/fulcio/pkg/identity/base"
)

type codefreshIssuer struct {
identity.Issuer
}

func Issuer(issuerURL string) identity.Issuer {
return &codefreshIssuer{base.Issuer(issuerURL)}
}

func (e *codefreshIssuer) Authenticate(ctx context.Context, token string, opts ...config.InsecureOIDCConfigOption) (identity.Principal, error) {
idtoken, err := identity.Authorize(ctx, token, opts...)
if err != nil {
return nil, fmt.Errorf("authorizing codefresh issuer: %w", err)
}
return WorkflowPrincipalFromIDToken(ctx, idtoken)
}