Skip to content

Commit

Permalink
Add commit sha and trigger to github workflow (#232)
Browse files Browse the repository at this point in the history
* add commit sha and trigger to github workflow

Signed-off-by: Asra Ali <asraa@google.com>

* update with non-type specific additional info

Signed-off-by: Asra Ali <asraa@google.com>
  • Loading branch information
asraa authored Nov 10, 2021
1 parent 5ec1b29 commit c0645e1
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 8 deletions.
7 changes: 6 additions & 1 deletion config/config.jsn
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
"IssuerURL": "https://oidc.dlorenc.dev",
"ClientID": "sigstore",
"Type": "spiffe"
}
},
"https://token.actions.githubusercontent.com": {
"IssuerURL": "https://token.actions.githubusercontent.com",
"ClientID": "sigstore",
"Type": "github-workflow"
}
}
}
26 changes: 25 additions & 1 deletion pkg/ca/googlecabeta/googleca.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,30 @@ func githubWorkflowSubject(id string) *privatecapb.CertificateConfig_SubjectConf
}
}

func AdditionalExtensions(subject *challenges.ChallengeResult) []*privatecapb.X509Extension {
res := []*privatecapb.X509Extension{}
if subject.TypeVal == challenges.GithubWorkflowValue {
if trigger, ok := subject.AdditionalInfo[challenges.GithubWorkflowTrigger]; ok {
res = append(res, &privatecapb.X509Extension{
ObjectId: &privatecapb.ObjectId{
ObjectIdPath: []int32{1, 3, 6, 1, 4, 1, 57264, 1, 3},
},
Value: []byte(trigger),
})
}

if sha, ok := subject.AdditionalInfo[challenges.GithubWorkflowSha]; ok {
res = append(res, &privatecapb.X509Extension{
ObjectId: &privatecapb.ObjectId{
ObjectIdPath: []int32{1, 3, 6, 1, 4, 1, 57264, 1, 2},
},
Value: []byte(sha),
})
}
}
return res
}

func KubernetesSubject(id string) *privatecapb.CertificateConfig_SubjectConfig {
return &privatecapb.CertificateConfig_SubjectConfig{
SubjectAltName: &privatecapb.SubjectAltNames{
Expand Down Expand Up @@ -184,7 +208,7 @@ func (c *CertAuthorityService) CreateCertificate(ctx context.Context, subj *chal
return nil, ca.ValidationError(err)
}

extensions := IssuerExtension(subj.Issuer)
extensions := append(IssuerExtension(subj.Issuer), AdditionalExtensions(subj)...)

req, err := Req(c.parent, privca, pubKeyBytes, extensions)
if err != nil {
Expand Down
22 changes: 21 additions & 1 deletion pkg/ca/x509ca/x509ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func (x *X509CA) CreateCertificateWithCA(certauth *X509CA, subject *challenges.C
}
cert.URIs = []*url.URL{k8sURI}
}
cert.ExtraExtensions = IssuerExtension(subject.Issuer)
cert.ExtraExtensions = append(IssuerExtension(subject.Issuer), AdditionalExtensions(subject)...)

finalCertBytes, err := x509.CreateCertificate(rand.Reader, cert, certauth.RootCA, subject.PublicKey, certauth.PrivKey)
if err != nil {
Expand All @@ -134,6 +134,26 @@ func (x *X509CA) CreateCertificateWithCA(certauth *X509CA, subject *challenges.C
return ca.CreateCSCFromDER(subject, finalCertBytes, nil)
}

func AdditionalExtensions(subject *challenges.ChallengeResult) []pkix.Extension {
res := []pkix.Extension{}
if subject.TypeVal == challenges.GithubWorkflowValue {
if trigger, ok := subject.AdditionalInfo[challenges.GithubWorkflowTrigger]; ok {
res = append(res, pkix.Extension{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 2},
Value: []byte(trigger),
})
}

if sha, ok := subject.AdditionalInfo[challenges.GithubWorkflowSha]; ok {
res = append(res, pkix.Extension{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 3},
Value: []byte(sha),
})
}
}
return res
}

func IssuerExtension(issuer string) []pkix.Extension {
if issuer == "" {
return nil
Expand Down
42 changes: 37 additions & 5 deletions pkg/challenges/challenges.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,21 @@ const (
KubernetesValue
)

type AdditionalInfo int

// Additional information that can be added as a cert extension.
const (
GithubWorkflowTrigger AdditionalInfo = iota
GithubWorkflowSha
)

type ChallengeResult struct {
Issuer string
TypeVal ChallengeType
PublicKey crypto.PublicKey
Value string
// Extra information from the token that can be added to extensions.
AdditionalInfo map[AdditionalInfo]string
}

func CheckSignature(pub crypto.PublicKey, proof []byte, email string) error {
Expand Down Expand Up @@ -165,6 +175,10 @@ func GithubWorkflow(ctx context.Context, principal *oidc.IDToken, pubKey crypto.
if err != nil {
return nil, err
}
additionalInfo, err := workflowInfoFromIDToken(principal)
if err != nil {
return nil, err
}

// Check the proof
if err := CheckSignature(pubKey, challenge, principal.Subject); err != nil {
Expand All @@ -184,10 +198,11 @@ func GithubWorkflow(ctx context.Context, principal *oidc.IDToken, pubKey crypto.

// Now issue cert!
return &ChallengeResult{
Issuer: issuer,
PublicKey: pubKey,
TypeVal: GithubWorkflowValue,
Value: workflowRef,
Issuer: issuer,
PublicKey: pubKey,
TypeVal: GithubWorkflowValue,
Value: workflowRef,
AdditionalInfo: additionalInfo,
}, nil
}

Expand Down Expand Up @@ -240,6 +255,24 @@ func workflowFromIDToken(token *oidc.IDToken) (string, error) {
return "https://github.com/" + claims.JobWorkflowRef, nil
}

func workflowInfoFromIDToken(token *oidc.IDToken) (map[AdditionalInfo]string, error) {
// Extract custom claims
var claims struct {
Sha string `json:"sha"`
Trigger string `json:"event_name"`
// The other fields that are present here seem to depend on the type
// of workflow trigger that initiated the action.
}
if err := token.Claims(&claims); err != nil {
return nil, err
}

// We use this in URIs, so it has to be a URI.
return map[AdditionalInfo]string{
GithubWorkflowSha: claims.Sha,
GithubWorkflowTrigger: claims.Trigger}, nil
}

func isSpiffeIDAllowed(host, spiffeID string) bool {
// Strip spiffe://
name := strings.TrimPrefix(spiffeID, "spiffe://")
Expand All @@ -251,5 +284,4 @@ func isSpiffeIDAllowed(host, spiffeID string) bool {
return true
}
return strings.Contains(spiffeDomain, "."+host)

}

0 comments on commit c0645e1

Please sign in to comment.