-
Notifications
You must be signed in to change notification settings - Fork 82
Open
Description
Recently on spire project, we needed to combine two matchers logic to correctly set the spire-server authorization logic, which should authorize spiffe ID that is either a member of the server trust domain or be included in a permissive list of admin IDs. Since the go-spiffe library doesn't provide this feature by default, we had to create a custom matcher and adapt it to a tlsconfig.Authorizer:
// matchMemberOrOneOf is a custom spiffeid.Matcher which will validate that the peerSpiffeID belongs to the server
// trust domain or if it is included in the admin_ids configuration permissive list.
func matchMemberOrOneOf(trustDomain spiffeid.TrustDomain, adminIds ...spiffeid.ID) spiffeid.Matcher {
permissiveIDsSet := make(map[spiffeid.ID]struct{})
for _, adminID := range adminIds {
permissiveIDsSet[adminID] = struct{}{}
}
return func(peerID spiffeid.ID) error {
if !peerID.MemberOf(trustDomain) {
if _, ok := permissiveIDsSet[peerID]; !ok {
return fmt.Errorf("unexpected trust domain in ID %q", peerID)
}
}
return nil
}
}
...
tlsconfig.AdaptMatcher(matchMemberOrOneOf(e.TrustDomain, e.AdminIDs...))This feature request proposes to add new mechanisms to go-spiffe library so that we could combine authorizers into logical clauses; I find it valuable to have at least AND and OR combinators, something like:
func AuthorizerOr(authorizers ...Authorizer) Authorizer {
return func(actual spiffeid.ID, verifiedChains [][]*x509.Certificate) error {
for _, authorizer := range authorizers {
err := authorizer(actual, verifiedChains)
if err == nil {
return nil
}
}
return errors.New("no matching authorizer")
}
}
func AuthorizerAnd(authorizers ...Authorizer) Authorizer {
return func(actual spiffeid.ID, verifiedChains [][]*x509.Certificate) error {
for _, authorizer := range authorizers {
err := authorizer(actual, verifiedChains)
if err != nil {
return err
}
}
return nil
}
}I am willing to open a PR on this in case of approval, and I would like to get some opinions here. What do you think?
Metadata
Metadata
Assignees
Labels
No labels