Repository: sigstore/fulcio
Pull request #1767 (2024-08-15 16:35:42)

fix: adding ci provider for meta-issuers
<!--
Thanks for opening a pull request! Please do not just delete this text.  The three fields below are mandatory.

Please remember to:
- This PR requires an issue. If it is a new feature, the issue should proceed the PR and will have allowed sufficent time for discussions to take place. Please use
issue tags such as "Closes #XYZ" or "Resolves sigstore/repo-name#XYZ".
  [documentation](https://docs.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword)
- ensure your commits are signed-off, as sigstore uses the [DCO](https://en.wikipedia.org/wiki/Developer_Certificate_of_Origin) using `git commit -s`, or `git commit -s --amend` if you want to amend already existing commits
- lastly, ensure there are no merge commits!

Thank you :)
-->
#### Summary
It set the ci-provider field for meta-issuers
<!--
 Explain the **motivation** for making this change. What existing problem does the pull request solve? How can reviewers test this PR?
-->

#### Release Note
<!--
Add a release note for each of the following conditions:

* Config changes (additions, deletions, updates)
* API additions—new endpoint, new response fields, or newly accepted request parameters
* Database changes (any)
* Websocket additions or changes
* Anything noteworthy to an administrator running private sigstore instances (err on the side of over-communicating)
* New features and improvements, including behavioural changes, UI changes and CLI changes
* Bug fixes and fixes of previous known issues
* Deprecation warnings, breaking changes, or compatibility notes

If no release notes are required write NONE. Use past-tense.

-->

#### Documentation
<!--

Does this change require an update to documentation? How will users implement your new feature?

Please reference a PR within https://docs.sigstore.dev

-->


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/sigstore/fulcio/pull/1767?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 50.32%. Comparing base [(`cf238ac`)](https://app.codecov.io/gh/sigstore/fulcio/commit/cf238accd68ef13e1e3425a5d87db2f352de173c?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore) to head [(`e68cf24`)](https://app.codecov.io/gh/sigstore/fulcio/commit/e68cf24c619d4243eca51be73f95063c056b0d74?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore).
> Report is 174 commits behind head on main.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #1767      +/-   ##
==========================================
- Coverage   57.93%   50.32%   -7.62%     
==========================================
  Files          50       70      +20     
  Lines        3119     4179    +1060     
==========================================
+ Hits         1807     2103     +296     
- Misses       1154     1843     +689     
- Partials      158      233      +75     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/sigstore/fulcio/pull/1767?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore).


Patch:
diff --git a/pkg/config/config.go b/pkg/config/config.go
index a229614..3d134d0 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -156,6 +156,7 @@ func (fc *FulcioConfig) GetIssuer(issuerURL string) (OIDCIssuer, bool) {
 				Type:          iss.Type,
 				IssuerClaim:   iss.IssuerClaim,
 				SubjectDomain: iss.SubjectDomain,
+				CIProvider:    iss.CIProvider,
 			}, true
 		}
 	}
diff --git a/pkg/identity/ciprovider/principal.go b/pkg/identity/ciprovider/principal.go
index 2066a04..a12f44c 100644
--- a/pkg/identity/ciprovider/principal.go
+++ b/pkg/identity/ciprovider/principal.go
@@ -106,7 +106,8 @@ func WorkflowPrincipalFromIDToken(ctx context.Context, token *oidc.IDToken) (ide
 	}
 	metadata, ok := cfg.CIIssuerMetadata[issuerCfg.CIProvider]
 	if !ok {
-		return nil, fmt.Errorf("metadata not found for ci provider %s", issuerCfg.CIProvider)
+		return nil, fmt.Errorf(
+			"metadata not found for ci provider %s, issuer: %s", issuerCfg.CIProvider, token.Issuer)
 	}
 	return ciPrincipal{
 		token,


Test patch:
diff --git a/pkg/config/config_network_test.go b/pkg/config/config_network_test.go
index 00f1398..d53a8e9 100644
--- a/pkg/config/config_network_test.go
+++ b/pkg/config/config_network_test.go
@@ -64,6 +64,18 @@ func TestLoadYamlConfig(t *testing.T) {
 		t.Errorf("expected https://oidc.eks.fantasy-land.amazonaws.com/id/CLUSTERIDENTIFIER, got %s", got.IssuerURL)
 	}
 
+	// Checking that the ci provider meta issuer has been set correctly
+	got, ok = cfg.GetIssuer("https://oidc.foo.foobar.bar.com/id/CLUSTERIDENTIFIER")
+	if !ok {
+		t.Error("expected true, got false")
+	}
+	if got.Type != "ci-provider" {
+		t.Errorf("expected ci-provider, got %s", got.Type)
+	}
+	if got.CIProvider != "github-workflow" {
+		t.Errorf("expected github-workflow, got %s", got.CIProvider)
+	}
+
 	if _, ok := cfg.GetIssuer("not_an_issuer"); ok {
 		t.Error("no error returned from an unconfigured issuer")
 	}
@@ -105,6 +117,18 @@ func TestLoadJsonConfig(t *testing.T) {
 		t.Errorf("expected https://oidc.eks.fantasy-land.amazonaws.com/id/CLUSTERIDENTIFIER, got %s", got.IssuerURL)
 	}
 
+	// Checking that the ci provider meta issuer has been set correctly
+	got, ok = cfg.GetIssuer("https://oidc.foo.foobar.bar.com/id/CLUSTERIDENTIFIER")
+	if !ok {
+		t.Error("expected true, got false")
+	}
+	if got.Type != "ci-provider" {
+		t.Errorf("expected ci-provider, got %s", got.Type)
+	}
+	if got.CIProvider != "github-workflow" {
+		t.Errorf("expected github-workflow, got %s", got.CIProvider)
+	}
+
 	if _, ok := cfg.GetIssuer("not_an_issuer"); ok {
 		t.Error("no error returned from an unconfigured issuer")
 	}
diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go
index 042fe9b..7e6564c 100644
--- a/pkg/config/config_test.go
+++ b/pkg/config/config_test.go
@@ -38,6 +38,10 @@ meta-issuers:
   https://oidc.eks.*.amazonaws.com/id/*:
     client-id: bar
     type: kubernetes
+  https://oidc.foo.*.bar.com/id/*:
+    client-id: bar
+    type: ci-provider
+    ci-provider: github-workflow
 `
 
 var validJSONCfg = `
@@ -54,6 +58,11 @@ var validJSONCfg = `
 		"https://oidc.eks.*.amazonaws.com/id/*": {
 			"ClientID": "bar",
 			"Type": "kubernetes"
+		},
+		"https://oidc.foo.*.bar.com/id/*": {
+			"ClientID": "bar",
+			"Type": "ci-provider",
+			"CiProvider": "github-workflow"
 		}
 	}
 }
diff --git a/pkg/config/fulcio_config_test.go b/pkg/config/fulcio_config_test.go
index e32bd04..57651fb 100644
--- a/pkg/config/fulcio_config_test.go
+++ b/pkg/config/fulcio_config_test.go
@@ -21,6 +21,7 @@ import (
 	"os"
 	"path/filepath"
 	"runtime"
+	"strings"
 	"testing"
 )
 
@@ -68,9 +69,32 @@ func TestLoadFulcioConfig(t *testing.T) {
 		}
 	}
 
-	for _, metaIssuer := range fulcioConfig.MetaIssuers {
-		if metaIssuer.ClientID != "sigstore" {
-			t.Errorf("expected sigstore, got %s", metaIssuer.ClientID)
+	for metaIssuerURLRegex := range fulcioConfig.MetaIssuers {
+		metaIssuerURL := strings.ReplaceAll(metaIssuerURLRegex, "*", "foo")
+		got, ok := fulcioConfig.GetIssuer(metaIssuerURL)
+		if !ok {
+			t.Errorf("expected true, got false, %s", metaIssuerURL)
+		}
+		if got.ClientID != "sigstore" {
+			t.Errorf("expected sigstore, got %s", got.ClientID)
+		}
+		if got.IssuerURL != metaIssuerURL {
+			t.Errorf("expected %s, got %s", metaIssuerURL, got.IssuerURL)
+		}
+
+		if string(got.Type) == "" {
+			t.Errorf("issuer Type should not be empty")
+		}
+		if got.Type == IssuerTypeCIProvider {
+			if got.CIProvider == "" {
+				t.Errorf("issuer that is CIProvider field shouldn't be empty when Type is ci-provider")
+			}
+			if _, ok := fulcioConfig.CIIssuerMetadata[got.CIProvider]; !ok {
+				t.Error("issuer with type ci-provider should have the same CI provider name as key for CIIssuerMetadata")
+			}
+		}
+		if _, ok := fulcioConfig.GetIssuer("not_an_issuer"); ok {
+			t.Error("no error returned from an unconfigured issuer")
 		}
 	}
 }