-
Notifications
You must be signed in to change notification settings - Fork 141
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move github principal to its own package
Remove github workflow logic from challenge result and put it in its own package. Signed-off-by: Nathan Smith <nathan@chainguard.dev>
- Loading branch information
Nathan Smith
committed
May 24, 2022
1 parent
ed8f649
commit 2917b0e
Showing
4 changed files
with
462 additions
and
141 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
// Copyright 2022 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 github | ||
|
||
import ( | ||
"context" | ||
"crypto/x509" | ||
"errors" | ||
"net/url" | ||
|
||
"github.com/coreos/go-oidc/v3/oidc" | ||
"github.com/sigstore/fulcio/pkg/ca/x509ca" | ||
"github.com/sigstore/fulcio/pkg/identity" | ||
) | ||
|
||
type workflowPrincipal struct { | ||
// Subject matches the 'sub' claim from the OIDC ID token this is what is | ||
// signed as proof of possession for Github workflow identities | ||
subject string | ||
|
||
// OIDC Issuer URL. Matches 'iss' claim from ID token. The real issuer URL is | ||
// https://token.actions.githubcontent.com/.well-known/openid-configution | ||
issuer string | ||
|
||
// The full URL to the workflow. This will be the set as SubjectAlternativeName URI in | ||
// the final certificate. | ||
url string | ||
|
||
// Commit SHA being built | ||
sha string | ||
|
||
// Event that triggered this workflow run. E.g "push", "tag" etc | ||
trigger string | ||
|
||
// Repository building built | ||
repository string | ||
|
||
// Workflow that is running | ||
workflow string | ||
|
||
// Git ref being built | ||
ref string | ||
} | ||
|
||
func WorkflowPrincipalFromIDToken(ctx context.Context, token *oidc.IDToken) (identity.Principal, error) { | ||
var claims struct { | ||
JobWorkflowRef string `json:"job_workflow_ref"` | ||
Sha string `json:"sha"` | ||
Trigger string `json:"event_name"` | ||
Repository string `json:"repository"` | ||
Workflow string `json:"workflow"` | ||
Ref string `json:"ref"` | ||
} | ||
if err := token.Claims(&claims); err != nil { | ||
return nil, err | ||
} | ||
|
||
if claims.JobWorkflowRef == "" { | ||
return nil, errors.New("missing job_workflow_ref claim in ID token") | ||
} | ||
if claims.Sha == "" { | ||
return nil, errors.New("missing sha claim in ID token") | ||
} | ||
if claims.Trigger == "" { | ||
return nil, errors.New("missing event_name claim in ID token") | ||
} | ||
if claims.Repository == "" { | ||
return nil, errors.New("missing repository claim in ID token") | ||
} | ||
if claims.Workflow == "" { | ||
return nil, errors.New("missing workflow claim in ID token") | ||
} | ||
if claims.Ref == "" { | ||
return nil, errors.New("missing ref claim in ID token") | ||
} | ||
|
||
return &workflowPrincipal{ | ||
subject: token.Subject, | ||
issuer: token.Issuer, | ||
url: `https://github.com/` + claims.JobWorkflowRef, | ||
sha: claims.Sha, | ||
trigger: claims.Trigger, | ||
repository: claims.Repository, | ||
workflow: claims.Workflow, | ||
ref: claims.Ref, | ||
}, nil | ||
} | ||
|
||
func (w workflowPrincipal) Name(ctx context.Context) string { | ||
return w.subject | ||
} | ||
|
||
func (w workflowPrincipal) Embed(ctx context.Context, cert *x509.Certificate) error { | ||
// Set workflow URL to SubjectAlternativeName on certificate | ||
parsed, err := url.Parse(w.url) | ||
if err != nil { | ||
return err | ||
} | ||
cert.URIs = []*url.URL{parsed} | ||
|
||
// Embed additional information into custom extensions | ||
cert.ExtraExtensions, err = x509ca.Extensions{ | ||
Issuer: w.issuer, | ||
GithubWorkflowTrigger: w.trigger, | ||
GithubWorkflowSHA: w.sha, | ||
GithubWorkflowName: w.workflow, | ||
GithubWorkflowRepository: w.repository, | ||
GithubWorkflowRef: w.ref, | ||
}.Render() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.