Merge pull request #1489 from smallstep/josh/authorization-principal-in-webhook

Include authorization principal in provisioner webhooks.
This commit is contained in:
Josh Drake 2023-07-24 21:22:46 -05:00 committed by GitHub
commit a1350b14fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 57 additions and 11 deletions

View file

@ -24,6 +24,7 @@ import (
"go.step.sm/linkedca" "go.step.sm/linkedca"
"github.com/smallstep/certificates/errs" "github.com/smallstep/certificates/errs"
"github.com/smallstep/certificates/webhook"
) )
// awsIssuer is the string used as issuer in the generated tokens. // awsIssuer is the string used as issuer in the generated tokens.
@ -521,7 +522,11 @@ func (p *AWS) AuthorizeSign(_ context.Context, token string) ([]SignOption, erro
commonNameValidator(payload.Claims.Subject), commonNameValidator(payload.Claims.Subject),
newValidityValidator(p.ctl.Claimer.MinTLSCertDuration(), p.ctl.Claimer.MaxTLSCertDuration()), newValidityValidator(p.ctl.Claimer.MinTLSCertDuration(), p.ctl.Claimer.MaxTLSCertDuration()),
newX509NamePolicyValidator(p.ctl.getPolicy().getX509()), newX509NamePolicyValidator(p.ctl.getPolicy().getX509()),
p.ctl.newWebhookController(data, linkedca.Webhook_X509), p.ctl.newWebhookController(
data,
linkedca.Webhook_X509,
webhook.WithAuthorizationPrincipal(doc.InstanceID),
),
), nil ), nil
} }
@ -804,6 +809,10 @@ func (p *AWS) AuthorizeSSHSign(_ context.Context, token string) ([]SignOption, e
// Ensure that all principal names are allowed // Ensure that all principal names are allowed
newSSHNamePolicyValidator(p.ctl.getPolicy().getSSHHost(), nil), newSSHNamePolicyValidator(p.ctl.getPolicy().getSSHHost(), nil),
// Call webhooks // Call webhooks
p.ctl.newWebhookController(data, linkedca.Webhook_SSH), p.ctl.newWebhookController(
data,
linkedca.Webhook_SSH,
webhook.WithAuthorizationPrincipal(doc.InstanceID),
),
), nil ), nil
} }

View file

@ -20,6 +20,7 @@ import (
"go.step.sm/linkedca" "go.step.sm/linkedca"
"github.com/smallstep/certificates/errs" "github.com/smallstep/certificates/errs"
"github.com/smallstep/certificates/webhook"
) )
// azureOIDCBaseURL is the base discovery url for Microsoft Azure tokens. // azureOIDCBaseURL is the base discovery url for Microsoft Azure tokens.
@ -403,7 +404,11 @@ func (p *Azure) AuthorizeSign(_ context.Context, token string) ([]SignOption, er
defaultPublicKeyValidator{}, defaultPublicKeyValidator{},
newValidityValidator(p.ctl.Claimer.MinTLSCertDuration(), p.ctl.Claimer.MaxTLSCertDuration()), newValidityValidator(p.ctl.Claimer.MinTLSCertDuration(), p.ctl.Claimer.MaxTLSCertDuration()),
newX509NamePolicyValidator(p.ctl.getPolicy().getX509()), newX509NamePolicyValidator(p.ctl.getPolicy().getX509()),
p.ctl.newWebhookController(data, linkedca.Webhook_X509), p.ctl.newWebhookController(
data,
linkedca.Webhook_X509,
webhook.WithAuthorizationPrincipal(identityObjectID),
),
), nil ), nil
} }
@ -421,7 +426,7 @@ func (p *Azure) AuthorizeSSHSign(_ context.Context, token string) ([]SignOption,
return nil, errs.Unauthorized("azure.AuthorizeSSHSign; sshCA is disabled for provisioner '%s'", p.GetName()) return nil, errs.Unauthorized("azure.AuthorizeSSHSign; sshCA is disabled for provisioner '%s'", p.GetName())
} }
_, name, _, _, _, err := p.authorizeToken(token) _, name, _, _, identityObjectID, err := p.authorizeToken(token)
if err != nil { if err != nil {
return nil, errs.Wrap(http.StatusInternalServerError, err, "azure.AuthorizeSSHSign") return nil, errs.Wrap(http.StatusInternalServerError, err, "azure.AuthorizeSSHSign")
} }
@ -473,7 +478,11 @@ func (p *Azure) AuthorizeSSHSign(_ context.Context, token string) ([]SignOption,
// Ensure that all principal names are allowed // Ensure that all principal names are allowed
newSSHNamePolicyValidator(p.ctl.getPolicy().getSSHHost(), nil), newSSHNamePolicyValidator(p.ctl.getPolicy().getSSHHost(), nil),
// Call webhooks // Call webhooks
p.ctl.newWebhookController(data, linkedca.Webhook_SSH), p.ctl.newWebhookController(
data,
linkedca.Webhook_SSH,
webhook.WithAuthorizationPrincipal(identityObjectID),
),
), nil ), nil
} }

View file

@ -21,6 +21,7 @@ import (
"go.step.sm/linkedca" "go.step.sm/linkedca"
"github.com/smallstep/certificates/errs" "github.com/smallstep/certificates/errs"
"github.com/smallstep/certificates/webhook"
) )
// gcpCertsURL is the url that serves Google OAuth2 public keys. // gcpCertsURL is the url that serves Google OAuth2 public keys.
@ -275,7 +276,11 @@ func (p *GCP) AuthorizeSign(_ context.Context, token string) ([]SignOption, erro
defaultPublicKeyValidator{}, defaultPublicKeyValidator{},
newValidityValidator(p.ctl.Claimer.MinTLSCertDuration(), p.ctl.Claimer.MaxTLSCertDuration()), newValidityValidator(p.ctl.Claimer.MinTLSCertDuration(), p.ctl.Claimer.MaxTLSCertDuration()),
newX509NamePolicyValidator(p.ctl.getPolicy().getX509()), newX509NamePolicyValidator(p.ctl.getPolicy().getX509()),
p.ctl.newWebhookController(data, linkedca.Webhook_X509), p.ctl.newWebhookController(
data,
linkedca.Webhook_X509,
webhook.WithAuthorizationPrincipal(ce.InstanceID),
),
), nil ), nil
} }
@ -442,6 +447,10 @@ func (p *GCP) AuthorizeSSHSign(_ context.Context, token string) ([]SignOption, e
// Ensure that all principal names are allowed // Ensure that all principal names are allowed
newSSHNamePolicyValidator(p.ctl.getPolicy().getSSHHost(), nil), newSSHNamePolicyValidator(p.ctl.getPolicy().getSSHHost(), nil),
// Call webhooks // Call webhooks
p.ctl.newWebhookController(data, linkedca.Webhook_SSH), p.ctl.newWebhookController(
data,
linkedca.Webhook_SSH,
webhook.WithAuthorizationPrincipal(ce.InstanceID),
),
), nil ), nil
} }

View file

@ -248,7 +248,12 @@ func (p *X5C) AuthorizeSign(_ context.Context, token string) ([]SignOption, erro
defaultPublicKeyValidator{}, defaultPublicKeyValidator{},
newValidityValidator(p.ctl.Claimer.MinTLSCertDuration(), p.ctl.Claimer.MaxTLSCertDuration()), newValidityValidator(p.ctl.Claimer.MinTLSCertDuration(), p.ctl.Claimer.MaxTLSCertDuration()),
newX509NamePolicyValidator(p.ctl.getPolicy().getX509()), newX509NamePolicyValidator(p.ctl.getPolicy().getX509()),
p.ctl.newWebhookController(data, linkedca.Webhook_X509, webhook.WithX5CCertificate(x5cLeaf)), p.ctl.newWebhookController(
data,
linkedca.Webhook_X509,
webhook.WithX5CCertificate(x5cLeaf),
webhook.WithAuthorizationPrincipal(x5cLeaf.Subject.CommonName),
),
}, nil }, nil
} }
@ -338,6 +343,11 @@ func (p *X5C) AuthorizeSSHSign(_ context.Context, token string) ([]SignOption, e
// Ensure that all principal names are allowed // Ensure that all principal names are allowed
newSSHNamePolicyValidator(p.ctl.getPolicy().getSSHHost(), p.ctl.getPolicy().getSSHUser()), newSSHNamePolicyValidator(p.ctl.getPolicy().getSSHHost(), p.ctl.getPolicy().getSSHUser()),
// Call webhooks // Call webhooks
p.ctl.newWebhookController(data, linkedca.Webhook_SSH, webhook.WithX5CCertificate(x5cLeaf)), p.ctl.newWebhookController(
data,
linkedca.Webhook_SSH,
webhook.WithX5CCertificate(x5cLeaf),
webhook.WithAuthorizationPrincipal(x5cLeaf.Subject.CommonName),
),
), nil ), nil
} }

View file

@ -499,7 +499,7 @@ func TestX5C_AuthorizeSign(t *testing.T) {
case *WebhookController: case *WebhookController:
assert.Len(t, 0, v.webhooks) assert.Len(t, 0, v.webhooks)
assert.Equals(t, linkedca.Webhook_X509, v.certType) assert.Equals(t, linkedca.Webhook_X509, v.certType)
assert.Len(t, 1, v.options) assert.Len(t, 2, v.options)
default: default:
assert.FatalError(t, fmt.Errorf("unexpected sign option of type %T", v)) assert.FatalError(t, fmt.Errorf("unexpected sign option of type %T", v))
} }
@ -805,7 +805,7 @@ func TestX5C_AuthorizeSSHSign(t *testing.T) {
case *WebhookController: case *WebhookController:
assert.Len(t, 0, v.webhooks) assert.Len(t, 0, v.webhooks)
assert.Equals(t, linkedca.Webhook_SSH, v.certType) assert.Equals(t, linkedca.Webhook_SSH, v.certType)
assert.Len(t, 1, v.options) assert.Len(t, 2, v.options)
default: default:
assert.FatalError(t, fmt.Errorf("unexpected sign option of type %T", v)) assert.FatalError(t, fmt.Errorf("unexpected sign option of type %T", v))
} }

View file

@ -68,6 +68,13 @@ func WithAttestationData(data *AttestationData) RequestBodyOption {
} }
} }
func WithAuthorizationPrincipal(p string) RequestBodyOption {
return func(rb *RequestBody) error {
rb.AuthorizationPrincipal = p
return nil
}
}
func WithSSHCertificateRequest(cr sshutil.CertificateRequest) RequestBodyOption { func WithSSHCertificateRequest(cr sshutil.CertificateRequest) RequestBodyOption {
return func(rb *RequestBody) error { return func(rb *RequestBody) error {
rb.SSHCertificateRequest = &SSHCertificateRequest{ rb.SSHCertificateRequest = &SSHCertificateRequest{

View file

@ -84,4 +84,6 @@ type RequestBody struct {
SCEPTransactionID string `json:"scepTransactionID,omitempty"` SCEPTransactionID string `json:"scepTransactionID,omitempty"`
// Only set for X5C provisioners // Only set for X5C provisioners
X5CCertificate *X5CCertificate `json:"x5cCertificate,omitempty"` X5CCertificate *X5CCertificate `json:"x5cCertificate,omitempty"`
// Set for X5C, AWS, GCP, and Azure provisioners
AuthorizationPrincipal string `json:"authorizationPrincipal,omitempty"`
} }