generated from sigstore/sigstore-project-template
-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for checking cert email against user config before signing.
This change adds a new config option: gitsign.matchCommitter. This option checks whether the certificate fetched matches the user configured email/name. For human users, this generally means that the SAN email in the cert matches the `user.email` Git config option. For non-email based identities (e.g. machine users), the SAN URI can be specified as the user name (since the URI isn't a valid email). Gitsign requires at least one condition to match for the check to succeed. This change does *not* enforce any constraints on verification, since this requires additional checking to know what IdP is considered valid.
- Loading branch information
Showing
5 changed files
with
157 additions
and
4 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Committer Verification | ||
|
||
Gitsign can be optionally configured to verify that the committer user identity | ||
matches the git user configuration (i.e. `user.name` and `user.email`) | ||
|
||
To enable committer verification, run `git config gitsign.matchCommitter true`. | ||
|
||
Committer verification is done by matching the certificate Subject Alternative | ||
Name (SAN) against the issued Fulcio certificate in the following order: | ||
|
||
1. An `EmailAddresses` cert value matches the committer `user.email`. This | ||
should be used for most human committer verification. | ||
2. A `URI` cert value matches the committer `user.name`. This should be used for | ||
most automated user committer verification. | ||
|
||
In the event that multiple SAN values are provided, verification will succeed if | ||
at least one value matches. | ||
|
||
## Configuring Automated Users | ||
|
||
If running in an environment where the authenticated user does **not** have a | ||
user email to bind against (i.e. GitHub Actions, other workload identity | ||
workflows), users are expected to be identified by the SAN URI instead. | ||
|
||
See https://github.com/sigstore/fulcio/blob/main/docs/oidc.md for more details | ||
|
||
### GitHub Actions | ||
|
||
```sh | ||
# This configures the SAN URI for the expected identity in the Fulcio cert. | ||
$ git config user.name "https://myorg/myrepo/path/to/workflow" | ||
# This configures GitHub UI to recognize the commit as coming from a GitHub Action. | ||
$ git config user.email [email protected] | ||
``` |
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
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,58 @@ | ||
package signature | ||
|
||
import ( | ||
"crypto/x509" | ||
"net/url" | ||
"testing" | ||
) | ||
|
||
func TestMatchSAN(t *testing.T) { | ||
for _, tc := range []struct { | ||
testname string | ||
cert *x509.Certificate | ||
name string | ||
email string | ||
want bool | ||
}{ | ||
{ | ||
testname: "email match", | ||
cert: &x509.Certificate{ | ||
EmailAddresses: []string{"[email protected]"}, | ||
}, | ||
name: "Foo Bar", | ||
email: "[email protected]", | ||
want: true, | ||
}, | ||
{ | ||
testname: "uri match", | ||
cert: &x509.Certificate{ | ||
URIs: []*url.URL{parseURL("https://github.com/foo/bar")}, | ||
}, | ||
name: "https://github.com/foo/bar", | ||
email: "[email protected]", | ||
want: true, | ||
}, | ||
{ | ||
testname: "no match", | ||
cert: &x509.Certificate{}, | ||
name: "https://github.com/foo/bar", | ||
email: "[email protected]", | ||
want: false, | ||
}, | ||
} { | ||
t.Run(tc.testname, func(t *testing.T) { | ||
got := matchSAN(tc.cert, tc.name, tc.email) | ||
if got != tc.want { | ||
t.Fatalf("got %t, want %t", got, tc.want) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func parseURL(raw string) *url.URL { | ||
u, err := url.Parse(raw) | ||
if err != nil { | ||
panic(err) | ||
} | ||
return u | ||
} |