Skip to content

Commit d2fcad3

Browse files
committed
Add support for Buildkite OIDC tokens
Add minimal support required to generate attestations for rubygems trusted publisher support in a Buildkite job 1. Teach sigstore-cli gem how to detect when it's running in a Buildkite job, and how to request a Buildkite OIDC token automatically 2. Teach sigstore gem how to parse an Buildkite OIDC token and generate the identity that fulcio uses for the x509 common name in certificates for Buildkite OIDC tokens With these changes, the following command works in a Buildkite job: bundle exec sigstore-cli sign <somefile> --bundle bundle.sigstore.json I've tested this using the pipeline defined in a gist: https://gist.github.com/yob/512f079e0586d49d125547ad548c08b5 The pipeline is private [1], however an example rekor log for a bundle created using this branch is at [2] [1] https://buildkite.com/yob-opensource/sigstore-ruby-test/ [2] https://search.sigstore.dev/?logIndex=176164097 Signed-off-by: James Healy <james@yob.id.au>
1 parent 27d8b53 commit d2fcad3

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

cli/lib/sigstore/cli/id_token.rb

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ class AmbientCredentialError < Sigstore::Error
99

1010
def self.detect_credential
1111
[
12-
GitHub
12+
GitHub,
13+
Buildkite
1314
# detect_gcp,
14-
# detect_buildkite,
1515
# detect_gitlab,
1616
# detect_circleci
1717
].each do |detector|
@@ -85,5 +85,34 @@ def call
8585
end
8686
end
8787
end
88+
89+
class Buildkite < IdToken
90+
91+
def call
92+
logger.debug { "looking for OIDC credentials" }
93+
unless ENV["BUILDKITE"]
94+
logger.debug { "environment doesn't look like Buildkite; giving up" }
95+
return
96+
end
97+
98+
raise AmbientCredentialError, "buildkite-agent executable not found" unless buildkite_agent_found?
99+
100+
request_token
101+
end
102+
103+
private
104+
105+
def buildkite_agent_found?
106+
`which buildkite-agent`
107+
$?.success?
108+
end
109+
110+
def request_token
111+
token = `buildkite-agent oidc request-token --audience 'sigstore'`
112+
raise AmbientCredentialError, "error requesting Buildkite OIDC token" unless $?.success?
113+
114+
token
115+
end
116+
end
88117
end
89118
end

lib/sigstore/oidc.rb

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ module OIDC
2020
"https://accounts.google.com" => "email",
2121
"https://oauth2.sigstore.dev/auth" => "email",
2222
"https://oauth2.sigstage.dev/auth" => "email",
23-
"https://token.actions.githubusercontent.com" => "job_workflow_ref"
23+
"https://token.actions.githubusercontent.com" => "job_workflow_ref",
24+
"https://agent.buildkite.com" => "pipeline_slug"
2425
}.freeze
2526
private_constant :KNOWN_OIDC_ISSUERS
2627

@@ -47,8 +48,19 @@ def initialize(raw_token)
4748
end
4849

4950
@identity = @unverified_claims[identity_claim]
50-
# https://github.com/sigstore/fulcio/blob/8311f93c01ea5b068a86d37c4bb51573289bfd69/pkg/identity/github/principal.go#L92
51-
@identity = "https://github.com/#{@identity}" if issuer == "https://token.actions.githubusercontent.com"
51+
if issuer == "https://token.actions.githubusercontent.com"
52+
# https://github.com/sigstore/fulcio/blob/8311f93c01ea5b068a86d37c4bb51573289bfd69/pkg/identity/github/principal.go#L92
53+
@identity = "https://github.com/#{@identity}"
54+
elsif issuer == "https://agent.buildkite.com"
55+
# https://github.com/sigstore/fulcio/blob/ec8a1d7a96125a1a624b9e69df892f987bebc41c/config/identity/config.yaml#L241
56+
org_slug = @unverified_claims["organization_slug"]
57+
if org_slug.nil?
58+
raise Error::InvalidIdentityToken,
59+
"identity token is missing required claim: organization_slug"
60+
end
61+
62+
@identity = "https://buildkite.com/#{org_slug}/#{@identity}"
63+
end
5264
else
5365
@identity = @unverified_claims["sub"]
5466
end

0 commit comments

Comments
 (0)