Skip to content

Commit 137679b

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 137679b

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

cli/lib/sigstore/cli/id_token.rb

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# frozen_string_literal: true
22

3+
require "open3"
4+
35
class Sigstore::CLI
46
class IdToken
57
include Sigstore::Loggable
@@ -9,9 +11,9 @@ class AmbientCredentialError < Sigstore::Error
911

1012
def self.detect_credential
1113
[
12-
GitHub
14+
GitHub,
15+
Buildkite
1316
# detect_gcp,
14-
# detect_buildkite,
1517
# detect_gitlab,
1618
# detect_circleci
1719
].each do |detector|
@@ -85,5 +87,33 @@ def call
8587
end
8688
end
8789
end
90+
91+
class Buildkite < IdToken
92+
def call
93+
logger.debug { "looking for OIDC credentials" }
94+
unless ENV["BUILDKITE"]
95+
logger.debug { "environment doesn't look like Buildkite; giving up" }
96+
return
97+
end
98+
99+
raise AmbientCredentialError, "buildkite-agent executable not found" unless buildkite_agent_found?
100+
101+
request_token
102+
end
103+
104+
private
105+
106+
def buildkite_agent_found?
107+
_, status = Open3.capture2(%w[which buildkite-agent])
108+
status.success?
109+
end
110+
111+
def request_token
112+
token, status = Open3.capture2(["buildkite-agent", "oidc", "request-token", "--audience", "sigstore"], &:read)
113+
raise AmbientCredentialError, "error requesting Buildkite OIDC token" unless status.success?
114+
115+
token.strip
116+
end
117+
end
88118
end
89119
end

lib/sigstore/oidc.rb

Lines changed: 16 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,20 @@ 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+
case issuer
52+
when "https://token.actions.githubusercontent.com"
53+
# https://github.com/sigstore/fulcio/blob/8311f93c01ea5b068a86d37c4bb51573289bfd69/pkg/identity/github/principal.go#L92
54+
@identity = "https://github.com/#{@identity}"
55+
when "https://agent.buildkite.com"
56+
# https://github.com/sigstore/fulcio/blob/ec8a1d7a96125a1a624b9e69df892f987bebc41c/config/identity/config.yaml#L241
57+
org_slug = @unverified_claims["organization_slug"]
58+
if org_slug.nil?
59+
raise Error::InvalidIdentityToken,
60+
"identity token is missing required claim: organization_slug"
61+
end
62+
63+
@identity = "https://buildkite.com/#{org_slug}/#{@identity}"
64+
end
5265
else
5366
@identity = @unverified_claims["sub"]
5467
end

0 commit comments

Comments
 (0)