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

Move codefresh and buildkite to ci-provider identity #1743

Merged
merged 7 commits into from
Aug 6, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 113 additions & 40 deletions config/identity/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
define:
- &github-type "github-workflow"
- &gitlab-type "gitlab-pipeline"
- &codefresh-type "codefresh-workflow"
- &buildkite-type "buildkite-job"
oidc-issuers:
https://accounts.google.com:
issuer-url: https://accounts.google.com
Expand All @@ -25,7 +27,8 @@ oidc-issuers:
https://agent.buildkite.com:
issuer-url: https://agent.buildkite.com
client-id: sigstore
type: buildkite-job
type: ci-provider
ci-provider: *buildkite-type
contact: support@buildkite.com
description: "Buildkite Agent OIDC tokens for job identity"
https://allow.pub:
Expand Down Expand Up @@ -84,7 +87,8 @@ oidc-issuers:
https://oidc.codefresh.io:
issuer-url: https://oidc.codefresh.io
client-id: sigstore
type: codefresh-workflow
type: ci-provider
ci-provider: *codefresh-type
contact: support@codefresh.io
description: "Codefresh OIDC tokens for job identity"
https://ops.gitlab.net:
Expand Down Expand Up @@ -120,45 +124,114 @@ meta-issuers:
ci-provider: *github-type
ci-issuer-metadata:
*github-type:
default-template-values:
url: "https://github.com"
extension-templates:
github-workflow-trigger: "event_name"
github-workflow-sha: "sha"
github-workflow-name: "workflow"
github-workflow-repository: "repository"
github-workflow-ref: "ref"
build-signer-uri: "{{ .url }}/{{ .job_workflow_ref }}"
build-signer-digest: "job_workflow_sha"
runner-environment: "runner_environment"
source-repository-uri: "{{ .url }}/{{ .repository }}"
source-repository-digest: "sha"
source-repository-ref: "ref"
source-repository-identifier: "repository_id"
source-repository-owner-uri: "{{ .url }}/{{ .repository_owner }}"
source-repository-owner-identifier: "repository_owner_id"
build-config-uri: "{{ .url }}/{{ .workflow_ref }}"
build-config-digest: "workflow_sha"
build-trigger: "event_name"
run-invocation-uri: "{{ .url }}/{{ .repository }}/actions/runs/{{ .run_id }}/attempts/{{ .run_attempt }}"
source-repository-visibility-at-signing: "repository_visibility"
subject-alternative-name-template: "{{ .url }}/{{ .job_workflow_ref }}"
default-template-values:
# url: URL of issuer, https://github.com
url: "https://github.com"
extension-templates:
# event_name: Event that triggered this workflow run. E.g "push", "tag"
github-workflow-trigger: "event_name"
javanlacerda marked this conversation as resolved.
Show resolved Hide resolved
# sha: Commit SHA being built
github-workflow-sha: "sha"
# workflow (Deprecated): Name of workflow that is running (mutable)
github-workflow-name: "workflow"
# repository: Name of repository being built
github-workflow-repository: "repository"
# ref: Git ref being built
github-workflow-ref: "ref"
# job_workflow_ref: Specific build instructions (i.e. reusable workflow)
build-signer-uri: "{{ .url }}/{{ .job_workflow_ref }}"
# job_workflow_sha: Commit SHA to specific build instructions
build-signer-digest: "job_workflow_sha"
# runner_environment: Whether the build took place in cloud or self-hosted infrastructure
runner-environment: "runner_environment"
# repository: Name of repository being built
source-repository-uri: "{{ .url }}/{{ .repository }}"
source-repository-digest: "sha"
source-repository-ref: "ref"
# repository_id: ID to the source repo
source-repository-identifier: "repository_id"
# repository_owner: Owner of the source repo (mutable)
source-repository-owner-uri: "{{ .url }}/{{ .repository_owner }}"
# repository_owner_id: ID of the source repo
source-repository-owner-identifier: "repository_owner_id"
# workflow_ref: Ref of top-level workflow that is running
build-config-uri: "{{ .url }}/{{ .workflow_ref }}"
# workflow_sha: Commit SHA of top-level workflow that is running
build-config-digest: "workflow_sha"
build-trigger: "event_name"
# run_id: ID of workflow run
# run_attempt: Attempt number of workflow run
run-invocation-uri: "{{ .url }}/{{ .repository }}/actions/runs/{{ .run_id }}/attempts/{{ .run_attempt }}"
# repository_visibility: Visibility of the source repo
source-repository-visibility-at-signing: "repository_visibility"
subject-alternative-name-template: "{{ .url }}/{{ .job_workflow_ref }}"
*gitlab-type:
default-template-values:
url: "https://gitlab.com"
url: "https://gitlab.com"
extension-templates:
build-signer-uri: "https://{{ .ci_config_ref_uri }}"
build-signer-digest: "ci_config_sha"
runner-environment: "runner_environment"
source-repository-uri: "{{ .url }}/{{ .repository }}"
source-repository-digest: "sha"
source-repository-ref: refs/{{if eq .ref_type "branch"}}heads/{{ else }}tags/{{end}}/{{ .ref }}
source-repository-identifier: "project_id"
source-repository-owner-uri: "{{ .url }}/{{ .namespace_path }}"
source-repository-owner-identifier: "namespace_id"
build-config-uri: "https://{{ .ci_config_ref_uri }}"
build-config-digest: "ci_config_sha"
build-trigger: "pipeline_source"
run-invocation-uri: "{{ .url }}/{{ .project_path }}/-/jobs/{{ .job_id }}"
source-repository-visibility-at-signing: "repository_visibility"
# url: The URL of the GitLab instance. https://gitlab.com
# ci_config_ref_uri: Ref of top-level pipeline definition.
# E.g. gitlab.com/my-group/my-project//.gitlab-ci.yml@refs/heads/main
build-signer-uri: "https://{{ .ci_config_ref_uri }}"
# ci_config_sha: Commit sha of top-level pipeline definition, and is
# only populated when `ciConfigRefURI` is local to the GitLab instance
build-signer-digest: "ci_config_sha"
# runner_environment: The type of runner used by the job. May be one of gitlab-hosted or self-hosted.
runner-environment: "runner_environment"
# repository: Repository building built
source-repository-uri: "{{ .url }}/{{ .repository }}"
# sha: Commit SHA being built
source-repository-digest: "sha"
# ref_type: The type of the ref
# E.g. "branch", "tag"
# ref: Git ref being built
source-repository-ref: refs/{{if eq .ref_type "branch"}}heads/{{ else }}tags/{{end}}/{{ .ref }}
# project_id: ID to the source repo
source-repository-identifier: "project_id"
# namespace_path: Owner of the source repo (mutable)
source-repository-owner-uri: "{{ .url }}/{{ .namespace_path }}"
# namespace_id: ID of the source repo
source-repository-owner-identifier: "namespace_id"
build-config-uri: "https://{{ .ci_config_ref_uri }}"
build-config-digest: "ci_config_sha"
# pipeline_source: Event that triggered this workflow run. E.g "push", "tag" etc
build-trigger: "pipeline_source"
# project_path: Repository building built
# job_id: job ID
run-invocation-uri: "{{ .url }}/{{ .project_path }}/-/jobs/{{ .job_id }}"
# project_visibility: Visibility of the source project
source-repository-visibility-at-signing: "project_visibility"
subject-alternative-name-template: "https://{{ .ci_config_ref_uri }}"
*codefresh-type:
default-template-values:
# We are setting the default value for "platform_url" as the ci-provider
# principal gives priority to the claimed value over the default
# when they have the same name. Then it will use the default "platform_url" value
# for cases that the claimed data doesn't exist.
# platform_url: Codefresh platform url
platform_url: "https://g.codefresh.io"
extension-templates:
# workflow_id: The ID of the specific workflow authorized in the claim.
# For example, 64f447c02199f903000gh20.
build-signer-uri: "{{.platform_url}}/build/{{ .workflow_id }}"
# runner_environment: Whether the build took place in cloud or self-hosted infrastructure
runner-environment: "runner_environment"
# scm_repo_url: Applies to Git push, PR, and manual Git trigger types.
# The SCM URL specifying the Git repository’s location.
# For example, https://github.com/codefresh-user/oidc-test
source-repository-uri: "scm_repo_url"
# scm_ref: Applies to Git push, PR, and manual Git trigger types.
# The SCM name of the branch or tag within the Git repository
# for which the workflow should execute. For example, main or v1.0.0.
source-repository-ref: "scm_ref"
# pipeline_id: Codefresh Pipeline id
build-config-uri: "{{.platform_url}}/api/pipelines/{{ .pipeline_id }}"
# account_name: Codefresh account name
# pipeline_name: Codefresh pipline name (project/pipeline)
# account_id: Codefresh account id
run-invocation-uri: "{{.platform_url}}/build/{{ .workflow_id }}"
subject-alternative-name-template: "{{.platform_url}}/{{.account_name}}/{{.pipeline_name}}:{{.account_id}}/{{.pipeline_id}}"
*buildkite-type:
default-template-values:
url: "https://buildkite.com"
subject-alternative-name-template: "{{.url}}/{{.organization_slug}}/{{.pipeline_slug}}"
2 changes: 1 addition & 1 deletion docs/oidc.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ To add a new OIDC issuer:

* Add the new issuer to the [configuration](https://github.com/sigstore/fulcio/blob/main/config/identity/config.yaml).
* Attention: If your issuer is for a CI provider, you should set the `type` as `ci-provider` and set the field `ci-provider` with the name of your provider. You should also fill the `ci-issuer-metadata` with the `default-template-values`, `extension-templates` and `subject-alternative-name-template`, following the pattern defined on the example ([example](tbd after migrating the github to ci-provider)).
* Important notes: The `extension-templates` and the `subject-alternative-name-template` follows the templates [pattern](https://pkg.go.dev/text/template). The name used to fill the `ci-provider` field has to be the same used as key for `ci-issuer-metadata`, we suggest to use a variable for this.
* Important notes: The `extension-templates` and the `subject-alternative-name-template` follows the templates [pattern](https://pkg.go.dev/text/template). The name used to fill the `ci-provider` field has to be the same used as key for `ci-issuer-metadata`, we suggest to use a variable for this. If you set a `default-template-value` with the same name of a claim key, the claimed value will have priority over the default one.
* If your issuer is not for a CI provider, you need to follow the next steps:
* Add the new issuer to the [`identity` folder](https://github.com/sigstore/fulcio/tree/main/pkg/identity) ([example](https://github.com/sigstore/fulcio/tree/main/pkg/identity/email)). You will define an `Issuer` type and a way to map the token to the certificate extensions.
* Define a constant with the issuer type name in the [configuration](https://github.com/sigstore/fulcio/blob/afeadb3b7d11f704489637cabc4e150dea3e00ed/pkg/config/config.go#L213-L221), add update the [tests](https://github.com/sigstore/fulcio/blob/afeadb3b7d11f704489637cabc4e150dea3e00ed/pkg/config/config_test.go#L473-L503)
Expand Down
6 changes: 3 additions & 3 deletions pkg/identity/ciprovider/principal.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ func applyTemplateOrReplace(extValueTemplate string, tokenClaims map[string]stri
// default data provided by the yaml file.
// The order here matter because we want to override the claimed data
// with the default data.
// The default data will have priority over the claimed data.
// The claimed data will have priority over the default data.
mergedData := make(map[string]string)
for k, v := range tokenClaims {
for k, v := range issuerMetadata {
mergedData[k] = v
}
for k, v := range issuerMetadata {
for k, v := range tokenClaims {
javanlacerda marked this conversation as resolved.
Show resolved Hide resolved
mergedData[k] = v
}

Expand Down
20 changes: 19 additions & 1 deletion pkg/identity/ciprovider/principal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,12 @@ func TestApplyTemplateOrReplace(t *testing.T) {
"ref_gitlab": "main",
"ref_type_tag": "tag",
"ref_tag": "1.0.0",
"claim_foo": "bar",
}
issuerMetadata := map[string]string{
"url": "https://github.com",
"url": "https://github.com",
"claim_foo": "default",
"default_foo": "default_bar",
}

tests := map[string]struct {
Expand Down Expand Up @@ -283,6 +286,21 @@ func TestApplyTemplateOrReplace(t *testing.T) {
ExpectedResult: "refs/tags/1.0.0",
ExpectErr: false,
},
`Raise error for empty key in comparison`: {
Template: `{{if eq . ""}}foo{{else}}bar{{end}}`,
ExpectedResult: "",
ExpectErr: true,
},
`Should use default when claim doesn't exist`: {
Template: "default_foo",
ExpectedResult: "default_bar",
ExpectErr: false,
},
`Should prior claims over defaults when they has the same name`: {
Template: "claim_foo",
ExpectedResult: "bar",
ExpectErr: false,
},
}

for name, test := range tests {
Expand Down
Loading