Skip to content

Commit

Permalink
Add more Buildkite tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sj26 committed Jan 16, 2023
1 parent fd1a2f1 commit 23ce160
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
3 changes: 3 additions & 0 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,9 @@ func Test_issuerToChallengeClaim(t *testing.T) {
if claim := issuerToChallengeClaim(IssuerTypeURI); claim != "sub" {
t.Fatalf("expected sub subject claim for URI issuer, got %s", claim)
}
if claim := issuerToChallengeClaim(IssuerTypeBuildkiteJob); claim != "sub" {
t.Fatalf("expected sub subject claim for Buildkite issuer, got %s", claim)
}
if claim := issuerToChallengeClaim(IssuerTypeGithubWorkflow); claim != "sub" {
t.Fatalf("expected sub subject claim for GitHub issuer, got %s", claim)
}
Expand Down
98 changes: 98 additions & 0 deletions pkg/server/grpc_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ func TestGetConfiguration(t *testing.T) {
_, uriIssuer := newOIDCIssuer(t)
_, usernameIssuer := newOIDCIssuer(t)
_, k8sIssuer := newOIDCIssuer(t)
_, buildkiteIssuer := newOIDCIssuer(t)
_, gitHubIssuer := newOIDCIssuer(t)

issuerDomain, err := url.Parse(usernameIssuer)
Expand Down Expand Up @@ -210,6 +211,11 @@ func TestGetConfiguration(t *testing.T) {
"SubjectDomain": %q,
"Type": "username"
},
%q: {
"IssuerURL": %q,
"ClientID": "sigstore",
"Type": "buildkite-job"
},
%q: {
"IssuerURL": %q,
"ClientID": "sigstore",
Expand All @@ -226,6 +232,7 @@ func TestGetConfiguration(t *testing.T) {
uriIssuer, uriIssuer, uriIssuer,
emailIssuer, emailIssuer,
usernameIssuer, usernameIssuer, issuerDomain.Hostname(),
buildkiteIssuer, buildkiteIssuer,
gitHubIssuer, gitHubIssuer,
k8sIssuer)))
if err != nil {
Expand Down Expand Up @@ -254,6 +261,7 @@ func TestGetConfiguration(t *testing.T) {
expectedIssuers := map[string]bool{
emailIssuer: true, spiffeIssuer: true, uriIssuer: true,
usernameIssuer: true, k8sIssuer: true, gitHubIssuer: true,
buildkiteIssuer: true,
}
for _, iss := range config.Issuers {
var issURL string
Expand Down Expand Up @@ -679,6 +687,96 @@ func TestAPIWithKubernetes(t *testing.T) {
}
}

// buildkiteClaims holds the additional JWT claims for Buildkite OIDC tokens
type buildkiteClaims struct {
OrganizationSlug string `json:"organization_slug"`
PipelineSlug string `json:"pipeline_slug"`
}

// Tests API for Buildkite subject types
func TestAPIWithBuildkite(t *testing.T) {
buildkiteSigner, buildkiteIssuer := newOIDCIssuer(t)

// Create a FulcioConfig that supports these issuers.
cfg, err := config.Read([]byte(fmt.Sprintf(`{
"OIDCIssuers": {
%q: {
"IssuerURL": %q,
"ClientID": "sigstore",
"Type": "buildkite-job"
}
}
}`, buildkiteIssuer, buildkiteIssuer)))
if err != nil {
t.Fatalf("config.Read() = %v", err)
}

claims := buildkiteClaims{
OrganizationSlug: "acme-inc",
PipelineSlug: "bash-example",
}
buildkiteSubject := fmt.Sprintf("organization:%s:pipeline:%s:ref:refs/heads/main:commit:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:step:build", claims.OrganizationSlug, claims.PipelineSlug)

// Create an OIDC token using this issuer's signer.
tok, err := jwt.Signed(buildkiteSigner).Claims(jwt.Claims{
Issuer: buildkiteIssuer,
IssuedAt: jwt.NewNumericDate(time.Now()),
Expiry: jwt.NewNumericDate(time.Now().Add(30 * time.Minute)),
Subject: buildkiteSubject,
Audience: jwt.Audience{"sigstore"},
}).Claims(&claims).CompactSerialize()
if err != nil {
t.Fatalf("CompactSerialize() = %v", err)
}

ctClient, eca := createCA(cfg, t)
ctx := context.Background()
server, conn := setupGRPCForTest(ctx, t, cfg, ctClient, eca)
defer func() {
server.Stop()
conn.Close()
}()

client := protobuf.NewCAClient(conn)

pubBytes, proof := generateKeyAndProof(buildkiteSubject, t)

// Hit the API to have it sign our certificate.
resp, err := client.CreateSigningCertificate(ctx, &protobuf.CreateSigningCertificateRequest{
Credentials: &protobuf.Credentials{
Credentials: &protobuf.Credentials_OidcIdentityToken{
OidcIdentityToken: tok,
},
},
Key: &protobuf.CreateSigningCertificateRequest_PublicKeyRequest{
PublicKeyRequest: &protobuf.PublicKeyRequest{
PublicKey: &protobuf.PublicKey{
Content: pubBytes,
},
ProofOfPossession: proof,
},
},
})
if err != nil {
t.Fatalf("SigningCert() = %v", err)
}

leafCert := verifyResponse(resp, eca, buildkiteIssuer, t)

// Expect URI values
if len(leafCert.URIs) != 1 {
t.Fatalf("unexpected length of leaf certificate URIs, expected 1, got %d", len(leafCert.URIs))
}
buildkiteUrl := fmt.Sprintf("https://buildkite.com/%s/%s", claims.OrganizationSlug, claims.PipelineSlug)
buildkiteUri, err := url.Parse(buildkiteUrl)
if err != nil {
t.Fatalf("failed to parse subject URI")
}
if *leafCert.URIs[0] != *buildkiteUri {
t.Fatalf("URIs do not match: Expected %v, got %v", buildkiteUri, leafCert.URIs[0])
}
}

// githubClaims holds the additional JWT claims for GitHub OIDC tokens
type githubClaims struct {
JobWorkflowRef string `json:"job_workflow_ref"`
Expand Down

0 comments on commit 23ce160

Please sign in to comment.