Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
Signed-off-by: Javan lacerda <javanlacerda@google.com>
  • Loading branch information
javanlacerda committed Jun 18, 2024
1 parent 228ecfe commit d9d4193
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 79 deletions.
3 changes: 3 additions & 0 deletions pkg/challenges/challenges.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/sigstore/fulcio/pkg/config"
"github.com/sigstore/fulcio/pkg/identity"
"github.com/sigstore/fulcio/pkg/identity/buildkite"
"github.com/sigstore/fulcio/pkg/identity/ciprovider"

Check failure on line 30 in pkg/challenges/challenges.go

View workflow job for this annotation

GitHub Actions / golangci-lint

could not import github.com/sigstore/fulcio/pkg/identity/ciprovider (-: # github.com/sigstore/fulcio/pkg/identity/ciprovider
"github.com/sigstore/fulcio/pkg/identity/email"
"github.com/sigstore/fulcio/pkg/identity/github"
"github.com/sigstore/fulcio/pkg/identity/gitlabcom"
Expand Down Expand Up @@ -75,6 +76,8 @@ func PrincipalFromIDToken(ctx context.Context, tok *oidc.IDToken) (identity.Prin
principal, err = uri.PrincipalFromIDToken(ctx, tok)
case config.IssuerTypeUsername:
principal, err = username.PrincipalFromIDToken(ctx, tok)
case config.IssuerCiProvider:
principal, err = ciprovider.WorkflowPrincipalFromIDToken(ctx, tok)
default:
return nil, fmt.Errorf("unsupported issuer: %s", iss.Type)
}
Expand Down
48 changes: 46 additions & 2 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@ import (
"net/http"
"net/url"
"os"
"path/filepath"
"reflect"
"regexp"
"runtime"
"strings"
"time"

"github.com/coreos/go-oidc/v3/oidc"
lru "github.com/hashicorp/golang-lru"
"github.com/sigstore/fulcio/pkg/certificate"
fulciogrpc "github.com/sigstore/fulcio/pkg/generated/protobuf"
"github.com/sigstore/fulcio/pkg/log"
"github.com/spiffe/go-spiffe/v2/spiffeid"
Expand Down Expand Up @@ -73,7 +76,9 @@ type OIDCIssuer struct {
ClientID string `json:"ClientID" yaml:"client-id,omitempty"`
// Used to determine the subject of the certificate and if additional
// certificate values are needed
Type IssuerType `json:"Type" yaml:"type,omitempty"`
Type IssuerType `json:"Type,omitempty" yaml:"type,omitempty"`
// The mapping for the issuer claims to the expected Extensions
CIProviderClaimsMapping certificate.Extensions `json:"ClaimsMapping,omitempty" yaml:"claims-mapping,omitempty"`
// Optional, if the issuer is in a different claim in the OIDC token
IssuerClaim string `json:"IssuerClaim,omitempty" yaml:"issuer-claim,omitempty"`
// The domain that must be present in the subject for 'uri' issuer types
Expand Down Expand Up @@ -103,6 +108,16 @@ func metaRegex(issuer string) (*regexp.Regexp, error) {
return regexp.Compile(replaced)
}

type Config struct {
Providers map[string]Provider
}
type Provider struct {
SubjectAlternativeName string `yaml:"subject-alternative-name,omitempty"`
Defaults map[string]string `yaml:"defaults,omitempty"`
OIDCIssuers []OIDCIssuer `yaml:"oidc-issuers,omitempty"`
MetaIssuers []OIDCIssuer `yaml:"meta-issuers,omitempty"`
}

// GetIssuer looks up the issuer configuration for an `issuerURL`
// coming from an incoming OIDC token. If no matching configuration
// is found, then it returns `false`.
Expand Down Expand Up @@ -283,6 +298,7 @@ const (
IssuerTypeSpiffe = "spiffe"
IssuerTypeURI = "uri"
IssuerTypeUsername = "username"
IssuerCiProvider = "ci-provider"
)

func parseConfig(b []byte) (cfg *FulcioConfig, err error) {
Expand Down Expand Up @@ -445,7 +461,33 @@ func Load(configPath string) (*FulcioConfig, error) {
if err != nil {
return nil, fmt.Errorf("read file: %w", err)
}
return Read(b)
config, err := Read(b)
if err != nil {
return config, err
}

var obj Config
_, path, _, _ := runtime.Caller(0)
basepath := filepath.Dir(path)
configFile, err := os.ReadFile(basepath + "/providers_config.yaml")
if err != nil {
fmt.Printf("yamlFile.Get err #%v ", err)
}
err = yaml.Unmarshal(configFile, &obj)
if err != nil {
fmt.Printf("Unmarshal: %v", err)
}
for _, v := range obj.Providers {
for _, issuer := range v.OIDCIssuers {
issuer.Type = "ci-provider"
config.OIDCIssuers[issuer.IssuerURL] = issuer
}
for _, issuer := range v.MetaIssuers {
config.MetaIssuers[issuer.IssuerURL] = issuer
}
}

return config, err
}

// Read parses the bytes of a config
Expand Down Expand Up @@ -525,6 +567,8 @@ func issuerToChallengeClaim(issType IssuerType, challengeClaim string) string {
return "sub"
case IssuerTypeUsername:
return "sub"
case IssuerCiProvider:
return "sub"
default:
return ""
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,19 @@

providers:
github-workflow:
extensions:
build-signer-digest: job_workflow_sha
source-repository-digest: sha
source-repository-ref: ref
source-repository-identifier: repository_id
run-invocation-uri: "{{.url}}/{{.repository}}/actions/runs/{{.run_id}}/"
uris:
- "{{.url}}/{{.job_workflow_ref}}"
defaults:
url: https://github.com
meta-issuers:
- issuer-url: "https://token.actions.githubusercontent.com/*"
client-id: "sigstore"
oidc-issuers:
- issuer-url: https://token.actions.githubusercontent.com
contact: tac@sigstore.dev
description: "GitHub Actions OIDC auth"
description: "GitHub Actions OIDC auth"
claims-mapping:
build-signer-digest: job_workflow_sha
source-repository-digest: sha
source-repository-ref: ref
source-repository-identifier: repository_id
run-invocation-uri: "{{.url}}/{{.repository}}/actions/runs/{{.run_id}}/"
subject-alternative-name: "{{.url}}/{{.job_workflow_ref}}"
defaults:
url: https://github.com
107 changes: 41 additions & 66 deletions pkg/identity/ciprovider/principal.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,44 +21,14 @@ import (
"fmt"
"html/template"
"net/url"
"os"
"strings"

"github.com/coreos/go-oidc/v3/oidc"
"github.com/sigstore/fulcio/pkg/certificate"
"github.com/sigstore/fulcio/pkg/config"
"github.com/sigstore/fulcio/pkg/identity"
"gopkg.in/yaml.v3"
)

type Config struct {
Providers map[config.IssuerType]Provider
}
type Provider struct {
Subject string
Extensions certificate.Extensions
Uris []string
Defaults map[string]string
OIDCIssuers []config.OIDCIssuer `yaml:"oidc-issuers,omitempty"`
MetaIssuers []config.OIDCIssuer `yaml:"meta-issuers,omitempty"`
Claims map[string]interface{}
}

func readConfig() Config {
var obj Config

configFile, err := os.ReadFile("providers_config.yaml")
if err != nil {
fmt.Printf("yamlFile.Get err #%v ", err)
}
err = yaml.Unmarshal(configFile, &obj)
if err != nil {
fmt.Printf("Unmarshal: %v", err)
}

return obj
}

func claimsToString(claims map[string]interface{}) map[string]string {
stringClaims := make(map[string]string)
for k, v := range claims {
Expand All @@ -67,7 +37,7 @@ func claimsToString(claims map[string]interface{}) map[string]string {
return stringClaims
}

func ApplyTemplate(path string, data map[string]string, defaultData map[string]string) string {
func applyTemplate(path string, data map[string]string, defaultData map[string]string) string {

// Here we merge the data from was claimed by the id token with the
// default data provided by the yaml file.
Expand Down Expand Up @@ -97,34 +67,39 @@ func ApplyTemplate(path string, data map[string]string, defaultData map[string]s
return mergedData[path]
}

type CiProvider struct {
config.OIDCIssuer
token *oidc.IDToken
}

func WorkflowPrincipalFromIDToken(ctx context.Context, token *oidc.IDToken) (identity.Principal, error) {
iss, ok := config.FromContext(ctx).GetIssuer(token.Issuer)
cfg, ok := config.FromContext(ctx).GetIssuer(token.Issuer)
if !ok {
return nil, fmt.Errorf("configuration can not be loaded for issuer %v", token.Issuer)
}
var claims map[string]interface{}
if err := token.Claims(&claims); err != nil {
return nil, err
}
configYaml := readConfig()
provider := configYaml.Providers[iss.Type]
provider.Claims = claims
provider.Subject = token.Subject
return provider, nil
return CiProvider{
cfg,
token,
}, nil
}

func (p Provider) Name(_ context.Context) string {
return p.Subject
func (p CiProvider) Name(_ context.Context) string {
return p.token.Subject
}

func (p Provider) Embed(_ context.Context, cert *x509.Certificate) error {
func (p CiProvider) Embed(_ context.Context, cert *x509.Certificate) error {

var claims map[string]interface{}
if err := p.token.Claims(&claims); err != nil {
return nil, err

Check failure on line 94 in pkg/identity/ciprovider/principal.go

View workflow job for this annotation

GitHub Actions / golangci-lint

too many return values
}

e := p.Extensions
e := p.CIProviderClaimsMapping
defaults := p.Defaults

Check failure on line 98 in pkg/identity/ciprovider/principal.go

View workflow job for this annotation

GitHub Actions / golangci-lint

p.Defaults undefined (type CiProvider has no field or method Defaults)
claims := claimsToString(p.Claims)

Check failure on line 99 in pkg/identity/ciprovider/principal.go

View workflow job for this annotation

GitHub Actions / golangci-lint

no new variables on left side of :=

Check failure on line 99 in pkg/identity/ciprovider/principal.go

View workflow job for this annotation

GitHub Actions / golangci-lint

cannot use claimsToString(p.Claims) (value of type map[string]string) as map[string]interface{} value in assignment

Check failure on line 99 in pkg/identity/ciprovider/principal.go

View workflow job for this annotation

GitHub Actions / golangci-lint

p.Claims undefined (type CiProvider has no field or method Claims)
uris := make([]*url.URL, len(p.Uris))

Check failure on line 100 in pkg/identity/ciprovider/principal.go

View workflow job for this annotation

GitHub Actions / golangci-lint

p.Uris undefined (type CiProvider has no field or method Uris)
for _, value := range p.Uris {

Check failure on line 101 in pkg/identity/ciprovider/principal.go

View workflow job for this annotation

GitHub Actions / golangci-lint

p.Uris undefined (type CiProvider has no field or method Uris)
url, err := url.Parse(ApplyTemplate(value, claims, defaults))
url, err := url.Parse(applyTemplate(value, claims, defaults))

Check failure on line 102 in pkg/identity/ciprovider/principal.go

View workflow job for this annotation

GitHub Actions / golangci-lint

cannot use claims (variable of type map[string]interface{}) as map[string]string value in argument to applyTemplate
if err != nil {
panic(err)
}
Expand All @@ -136,26 +111,26 @@ func (p Provider) Embed(_ context.Context, cert *x509.Certificate) error {
var err error
// Embed additional information into custom extensions
cert.ExtraExtensions, err = certificate.Extensions{
Issuer: ApplyTemplate(e.Issuer, claims, defaults),
GithubWorkflowTrigger: ApplyTemplate(e.GithubWorkflowTrigger, claims, defaults),
GithubWorkflowSHA: ApplyTemplate(e.GithubWorkflowSHA, claims, defaults),
GithubWorkflowName: ApplyTemplate(e.GithubWorkflowName, claims, defaults),
GithubWorkflowRepository: ApplyTemplate(e.GithubWorkflowRepository, claims, defaults),
GithubWorkflowRef: ApplyTemplate(e.GithubWorkflowRef, claims, defaults),
BuildSignerURI: ApplyTemplate(e.BuildSignerURI, claims, defaults),
BuildConfigDigest: ApplyTemplate(e.BuildConfigDigest, claims, defaults),
RunnerEnvironment: ApplyTemplate(e.RunnerEnvironment, claims, defaults),
SourceRepositoryURI: ApplyTemplate(e.SourceRepositoryURI, claims, defaults),
SourceRepositoryDigest: ApplyTemplate(e.SourceRepositoryDigest, claims, defaults),
SourceRepositoryRef: ApplyTemplate(e.SourceRepositoryRef, claims, defaults),
SourceRepositoryIdentifier: ApplyTemplate(e.SourceRepositoryIdentifier, claims, defaults),
SourceRepositoryOwnerURI: ApplyTemplate(e.SourceRepositoryOwnerURI, claims, defaults),
SourceRepositoryOwnerIdentifier: ApplyTemplate(e.SourceRepositoryOwnerIdentifier, claims, defaults),
BuildConfigURI: ApplyTemplate(e.BuildConfigURI, claims, defaults),
BuildSignerDigest: ApplyTemplate(e.BuildSignerDigest, claims, defaults),
BuildTrigger: ApplyTemplate(e.BuildTrigger, claims, defaults),
RunInvocationURI: ApplyTemplate(e.RunInvocationURI, claims, defaults),
SourceRepositoryVisibilityAtSigning: ApplyTemplate(e.SourceRepositoryVisibilityAtSigning, claims, defaults),
Issuer: applyTemplate(e.Issuer, claims, defaults),

Check failure on line 114 in pkg/identity/ciprovider/principal.go

View workflow job for this annotation

GitHub Actions / golangci-lint

cannot use claims (variable of type map[string]interface{}) as map[string]string value in argument to applyTemplate
GithubWorkflowTrigger: applyTemplate(e.GithubWorkflowTrigger, claims, defaults),
GithubWorkflowSHA: applyTemplate(e.GithubWorkflowSHA, claims, defaults),
GithubWorkflowName: applyTemplate(e.GithubWorkflowName, claims, defaults),
GithubWorkflowRepository: applyTemplate(e.GithubWorkflowRepository, claims, defaults),
GithubWorkflowRef: applyTemplate(e.GithubWorkflowRef, claims, defaults),
BuildSignerURI: applyTemplate(e.BuildSignerURI, claims, defaults),
BuildConfigDigest: applyTemplate(e.BuildConfigDigest, claims, defaults),
RunnerEnvironment: applyTemplate(e.RunnerEnvironment, claims, defaults),
SourceRepositoryURI: applyTemplate(e.SourceRepositoryURI, claims, defaults),
SourceRepositoryDigest: applyTemplate(e.SourceRepositoryDigest, claims, defaults),
SourceRepositoryRef: applyTemplate(e.SourceRepositoryRef, claims, defaults),
SourceRepositoryIdentifier: applyTemplate(e.SourceRepositoryIdentifier, claims, defaults),
SourceRepositoryOwnerURI: applyTemplate(e.SourceRepositoryOwnerURI, claims, defaults),
SourceRepositoryOwnerIdentifier: applyTemplate(e.SourceRepositoryOwnerIdentifier, claims, defaults),
BuildConfigURI: applyTemplate(e.BuildConfigURI, claims, defaults),
BuildSignerDigest: applyTemplate(e.BuildSignerDigest, claims, defaults),
BuildTrigger: applyTemplate(e.BuildTrigger, claims, defaults),
RunInvocationURI: applyTemplate(e.RunInvocationURI, claims, defaults),
SourceRepositoryVisibilityAtSigning: applyTemplate(e.SourceRepositoryVisibilityAtSigning, claims, defaults),
}.Render()
if err != nil {
return err
Expand Down
3 changes: 3 additions & 0 deletions pkg/server/issuer_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/sigstore/fulcio/pkg/config"
"github.com/sigstore/fulcio/pkg/identity"
"github.com/sigstore/fulcio/pkg/identity/buildkite"
"github.com/sigstore/fulcio/pkg/identity/ciprovider"
"github.com/sigstore/fulcio/pkg/identity/codefresh"
"github.com/sigstore/fulcio/pkg/identity/email"
"github.com/sigstore/fulcio/pkg/identity/github"
Expand Down Expand Up @@ -70,6 +71,8 @@ func getIssuer(meta string, i config.OIDCIssuer) identity.Issuer {
return uri.Issuer(issuerURL)
case config.IssuerTypeUsername:
return username.Issuer(issuerURL)
case config.IssuerCiProvider:
return ciprovider.Issuer(issuerURL)
}
return nil
}

0 comments on commit d9d4193

Please sign in to comment.