Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for signature verification predicates #285

Merged
merged 12 commits into from
May 6, 2021

Conversation

IainSteers
Copy link
Contributor

@IainSteers IainSteers commented Apr 16, 2021

This PR introduces support for policy-bot to verify the presence of git commit signatures in a pull request.

  • New predicate has_valid_signatures, this predicate should be used to test if commits are signed and their signatures valid.
  • New predicate has_valid_signatures_by, commits are required to have valid signatures and additionally the signatures must be authenticated as one of the valid users/team/org members listed.
  • New predicate has_valid_signatures_by_key, commits are required to have valid signatures and additionally the signatures must be attributed to one of the key_ids listed.
approval_rules:

- name: commits are signed
  if:
    has_valid_signatures: true

- name: commits are signed by excavator
  if:
    has_valid_signatures_by:
      users: ["svc-excavator-bot"]
      
- name: commits are signed by known excavator key
  if:
    has_valid_signatures_by_keys:
      key_ids: ["3AA5C34371567BD2"]

policy/predicate/signature.go Show resolved Hide resolved
policy/predicate/signature.go Outdated Show resolved Hide resolved
pull/context.go Outdated Show resolved Hide resolved
pull/github.go Show resolved Hide resolved
@IainSteers IainSteers force-pushed the isteers/signature-predicates branch 3 times, most recently from 9ad431e to a5a6357 Compare April 19, 2021 07:10
@IainSteers IainSteers marked this pull request as ready for review April 19, 2021 07:13
README.md Outdated Show resolved Hide resolved
Copy link
Member

@bluekeyes bluekeyes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm interested to see how these predicates end up being used. I can see uses as disapproval conditions and in combination with other conditions, but I'm curious if they will be used on their own. Maybe commit signatures could replace the forgeable (without additional pre-receive hooks) author and committer checks to some extent?

README.md Outdated
# "has_valid_signatures_by" is satisfied if the commits in the pull request
# all have git commit signatures that have been verified by GitHub, and
# the authenticated signatures are attributed to a user in the users list
# or belong to any of the listed organizations or teams.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# or belong to any of the listed organizations or teams.
# or belong to a user in any of the listed organizations or teams.

README.md Show resolved Hide resolved
Comment on lines 37 to 39
if !pred {
return true, "", nil
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my note above about what it means when this predicate is false. If we do keep the current implementation, let's do this check before getting the commits.

policy/predicate/signature.go Show resolved Hide resolved
policy/predicate/signature.go Show resolved Hide resolved
pull/context.go Outdated
Comment on lines 208 to 214
type Signature interface {
GetEmail() string
GetIsValid() bool
GetPayload() string
GetSignature() string
GetSigner() string
GetState() string
GetSignedByGitHub() bool
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sold on the use of an interface to represent the different signature types here, especially since the only difference is the addition of the ID field in the GPG case. It stands out in comparison to the rest of the pull.Context return types, which are all simple concrete structs.

Using a pointer to a concrete Signature in Commit also makes it clearer that the value may not be present.

What do you think about using a concrete type with an optional KeyID field and maybe a Type field (similar to the Type field on Reviewer, especially since you already defined a type type for use with GraphQL)? Since you already have functions to convert the GitHub API types into the pull.Context types, I don't think it would change the code much.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fair. I mostly went with the interface out of habit rather than a particular need.

You're right it didn't change the code much and arguably given then types involved it feels neater now.

pull/github.go Outdated
const (
SignatureGpg SignatureType = "GpgSignature"
SignatureSmime SignatureType = "SmimeSignature"
SignatureUnknown SignatureType = "UnknownSignature"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this type used anywhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I thought it might be necessary at one point but forgot to remove it. Done

Copy link
Member

@bluekeyes bluekeyes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One non-blocking comment on minimizing unused fields, but otherwise this looks good to me.

pull/context.go Outdated
Comment on lines 208 to 214
type Signature struct {
Type SignatureType
Email string
IsValid bool
KeyID string
Payload string
Signature string
Signer string
State string
WasSignedByGitHub bool
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Historically, I've tried to only expose fields that were actually used and then add additional fields as needed. It looks like WasSignedByGitHub, Email, Payload, Signature, and maybe others are not used. What do you think about removing those for now?

@IainSteers IainSteers force-pushed the isteers/signature-predicates branch from db40ddc to 46f36b5 Compare May 6, 2021 16:02
@IainSteers IainSteers force-pushed the isteers/signature-predicates branch from 46f36b5 to 4dee23c Compare May 6, 2021 16:10
@IainSteers IainSteers merged commit 762711a into develop May 6, 2021
@IainSteers IainSteers deleted the isteers/signature-predicates branch May 6, 2021 16:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants