Add ca-url based audience for AWS tokens

Fixes smallstep/step#156
This commit is contained in:
Mariano Cano 2019-06-06 12:49:51 -07:00
parent 4fa9e9333d
commit 2491593cdd

View file

@ -131,11 +131,12 @@ type AWS struct {
Claims *Claims `json:"claims,omitempty"`
claimer *Claimer
config *awsConfig
audiences Audiences
}
// GetID returns the provisioner unique identifier.
func (p *AWS) GetID() string {
return "aws:" + p.Name
return "aws/" + p.Name
}
// GetTokenID returns the identifier of the token.
@ -170,7 +171,7 @@ func (p *AWS) GetEncryptedKey() (kid string, key string, ok bool) {
// GetIdentityToken retrieves the identity document and it's signature and
// generates a token with them.
func (p *AWS) GetIdentityToken() (string, error) {
func (p *AWS) GetIdentityToken(caURL string) (string, error) {
// Initialize the config if this method is used from the cli.
if err := p.assertConfig(); err != nil {
return "", err
@ -196,6 +197,11 @@ func (p *AWS) GetIdentityToken() (string, error) {
return "", err
}
audience, err := generateSignAudience(caURL, p.GetID())
if err != nil {
return "", err
}
// Create unique ID for Trust On First Use (TOFU). Only the first instance
// per provisioner is allowed as we don't have a way to trust the given
// sans.
@ -216,7 +222,7 @@ func (p *AWS) GetIdentityToken() (string, error) {
Claims: jose.Claims{
Issuer: awsIssuer,
Subject: idoc.InstanceID,
Audience: []string{p.GetID()},
Audience: []string{audience},
Expiry: jose.NewNumericDate(now.Add(5 * time.Minute)),
NotBefore: jose.NewNumericDate(now),
IssuedAt: jose.NewNumericDate(now),
@ -254,6 +260,7 @@ func (p *AWS) Init(config Config) (err error) {
if p.config, err = newAWSConfig(); err != nil {
return err
}
p.audiences = config.Audiences.WithFragment(p.GetID())
return nil
}
@ -381,14 +388,18 @@ func (p *AWS) authorizeToken(token string) (*awsPayload, error) {
// more than a few minutes.
now := time.Now().UTC()
if err = payload.ValidateWithLeeway(jose.Expected{
Issuer: awsIssuer,
Subject: doc.InstanceID,
Audience: []string{p.GetID()},
Time: now,
Issuer: awsIssuer,
Subject: doc.InstanceID,
Time: now,
}, time.Minute); err != nil {
return nil, errors.Wrapf(err, "invalid token")
}
// validate audiences with the defaults
if !matchesAudience(payload.Audience, p.audiences.Sign) {
return nil, errors.New("invalid token: invalid audience claim (aud)")
}
// validate accounts
if len(p.Accounts) > 0 {
var found bool