diff --git a/CHANGELOG.md b/CHANGELOG.md index 734c125c4..6e664fba5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,19 @@ -## Next (Unreleased) +## 1.0.0 (Unreleased) CHANGES: - * core: HA lock file is no longer copied during `operator migrate` [GH-5503] * core: Tokens are now prefixed by a designation to indicate what type of token they are. Service tokens start with `s.` and batch tokens start with `b.`. Existing tokens will still work (they are all of service type and will be considered as such). Prefixing allows us to be more efficient when consuming a token, which keeps the critical path of requests faster. +IMPROVEMENTS: + + * auth/token: New tokens are salted using SHA2-256 HMAC instead of SHA1 hash + +## 0.11.4 (Unreleased) + FEATURES: * Transit Key Trimming: Keys in transit secret engine can now be trimmed to @@ -18,21 +23,28 @@ FEATURES: IMPROVEMENTS: - * auth/token: New tokens are salted using SHA2-256 HMAC instead of SHA1 hash + * core: Add last WAL in leader/health output for easier debugging [GH-5523] * identity: Identity names will now be handled case insensitively by default. This includes names of entities, aliases and groups [GH-5404] + * secrets/aws: Added role-option max_sts_ttl to cap TTL for AWS STS + credentials [GH-5500] * secret/azure: Credentials can now be generated against an existing service principal. * secret/database: Allow Cassandra user to be non-superuser so long as it has role creation permissions [GH-5402] * secret/radius: Allow setting the NAS Identifier value in the generated packet [GH-5465] + * secret/ssh: Allow usage of JSON arrays when setting zero addresses [GH-5528] * ui: Allow viewing and updating Vault license via the UI * ui: Onboarding will now display your progress through the chosen tutorials - * ui: Dynamic secret backends obfuscate sensitive data by default and visibility is toggleable + * ui: Dynamic secret backends obfuscate sensitive data by default and + visibility is toggleable BUG FIXES: * agent: Fix potential hang during agent shutdown [GH-5026] + * auth/ldap: Fix listing of users/groups that contain slashes [GH-5537] + * command/migration: Don't copy HA locks [GH-5503] + * core: Fix memory leak during some expiration calls [GH-5505] * core: Fix generate-root operations requiring empty `otp` to be provided instead of an empty body [GH-5495] * identity: Remove lookup check during alias removal from entity [GH-5524] diff --git a/builtin/logical/aws/backend_test.go b/builtin/logical/aws/backend_test.go index 86acc65bd..5eb76104d 100644 --- a/builtin/logical/aws/backend_test.go +++ b/builtin/logical/aws/backend_test.go @@ -652,6 +652,7 @@ func testAccStepReadPolicy(t *testing.T, name string, value string) logicaltest. "policy_document": value, "credential_types": []string{iamUserCred, federationTokenCred}, "default_sts_ttl": int64(0), + "max_sts_ttl": int64(0), } if !reflect.DeepEqual(resp.Data, expected) { return fmt.Errorf("bad: got: %#v\nexpected: %#v", resp.Data, expected) @@ -749,6 +750,7 @@ func TestBackend_iamUserManagedInlinePolicies(t *testing.T) { "credential_types": []string{iamUserCred}, "role_arns": []string(nil), "default_sts_ttl": int64(0), + "max_sts_ttl": int64(0), } logicaltest.Test(t, logicaltest.TestCase{ AcceptanceTest: true, @@ -828,6 +830,7 @@ func TestBackend_RoleDefaultSTSTTL(t *testing.T) { "role_arns": []string{fmt.Sprintf("arn:aws:iam::%s:role/%s", awsAccountID, roleName)}, "credential_type": assumedRoleCred, "default_sts_ttl": minAwsAssumeRoleDuration, + "max_sts_ttl": minAwsAssumeRoleDuration, } logicaltest.Test(t, logicaltest.TestCase{ AcceptanceTest: true, @@ -883,6 +886,7 @@ func testAccStepReadArnPolicy(t *testing.T, name string, value string) logicalte "policy_document": "", "credential_types": []string{iamUserCred}, "default_sts_ttl": int64(0), + "max_sts_ttl": int64(0), } if !reflect.DeepEqual(resp.Data, expected) { return fmt.Errorf("bad: got: %#v\nexpected: %#v", resp.Data, expected) diff --git a/builtin/logical/aws/path_roles.go b/builtin/logical/aws/path_roles.go index ae225e379..a3a30f561 100644 --- a/builtin/logical/aws/path_roles.go +++ b/builtin/logical/aws/path_roles.go @@ -67,6 +67,11 @@ GetFederationToken API call, acting as a filter on permissions available.`, Description: fmt.Sprintf("Default TTL for %s and %s credential types when no TTL is explicitly requested with the credentials", assumedRoleCred, federationTokenCred), }, + "max_sts_ttl": &framework.FieldSchema{ + Type: framework.TypeDurationSecond, + Description: fmt.Sprintf("Max allowed TTL for %s and %s credential types", assumedRoleCred, federationTokenCred), + }, + "arn": &framework.FieldSchema{ Type: framework.TypeString, Description: `Deprecated; use role_arns or policy_arns instead. ARN Reference to a managed policy @@ -222,6 +227,23 @@ func (b *backend) pathRolesWrite(ctx context.Context, req *logical.Request, d *f roleEntry.DefaultSTSTTL = time.Duration(defaultSTSTTLRaw.(int)) * time.Second } + if maxSTSTTLRaw, ok := d.GetOk("max_sts_ttl"); ok { + if legacyRole != "" { + return logical.ErrorResponse("cannot supply deprecated role or policy parameters with max_sts_ttl"), nil + } + if !strutil.StrListContains(roleEntry.CredentialTypes, assumedRoleCred) && !strutil.StrListContains(roleEntry.CredentialTypes, federationTokenCred) { + return logical.ErrorResponse(fmt.Sprintf("max_sts_ttl parameter only valid for %s and %s credential types", assumedRoleCred, federationTokenCred)), nil + } + + roleEntry.MaxSTSTTL = time.Duration(maxSTSTTLRaw.(int)) * time.Second + } + + if roleEntry.MaxSTSTTL > 0 && + roleEntry.DefaultSTSTTL > 0 && + roleEntry.DefaultSTSTTL > roleEntry.MaxSTSTTL { + return logical.ErrorResponse(`"default_sts_ttl" value must be less than or equal to "max_sts_ttl" value`), nil + } + if legacyRole != "" { roleEntry = upgradeLegacyPolicyEntry(legacyRole) if roleEntry.InvalidData != "" { @@ -402,6 +424,7 @@ type awsRoleEntry struct { ProhibitFlexibleCredPath bool `json:"prohibit_flexible_cred_path,omitempty"` // Disallow accessing STS credentials via the creds path and vice verse Version int `json:"version"` // Version number of the role format DefaultSTSTTL time.Duration `json:"default_sts_ttl"` // Default TTL for STS credentials + MaxSTSTTL time.Duration `json:"max_sts_ttl"` // Max allowed TTL for STS credentials } func (r *awsRoleEntry) toResponseData() map[string]interface{} { @@ -411,6 +434,7 @@ func (r *awsRoleEntry) toResponseData() map[string]interface{} { "role_arns": r.RoleArns, "policy_document": r.PolicyDocument, "default_sts_ttl": int64(r.DefaultSTSTTL.Seconds()), + "max_sts_ttl": int64(r.MaxSTSTTL.Seconds()), } if r.InvalidData != "" { respData["invalid_data"] = r.InvalidData diff --git a/builtin/logical/aws/path_roles_test.go b/builtin/logical/aws/path_roles_test.go index b0d4bff38..3ac2473e1 100644 --- a/builtin/logical/aws/path_roles_test.go +++ b/builtin/logical/aws/path_roles_test.go @@ -24,6 +24,7 @@ func TestBackend_PathListRoles(t *testing.T) { "role_arns": []string{"arn:aws:iam::123456789012:role/path/RoleName"}, "credential_type": assumedRoleCred, "default_sts_ttl": 3600, + "max_sts_ttl": 3600, } roleReq := &logical.Request{ diff --git a/builtin/logical/aws/path_user.go b/builtin/logical/aws/path_user.go index 99aa8bac3..99f09c6a3 100644 --- a/builtin/logical/aws/path_user.go +++ b/builtin/logical/aws/path_user.go @@ -68,6 +68,18 @@ func (b *backend) pathCredsRead(ctx context.Context, req *logical.Request, d *fr default: ttl = int64(d.Get("ttl").(int)) } + + var maxTTL int64 + if role.MaxSTSTTL > 0 { + maxTTL = int64(role.MaxSTSTTL.Seconds()) + } else { + maxTTL = int64(b.System().MaxLeaseTTL().Seconds()) + } + + if ttl > maxTTL { + ttl = maxTTL + } + roleArn := d.Get("role_arn").(string) var credentialType string diff --git a/website/source/api/secret/aws/index.html.md b/website/source/api/secret/aws/index.html.md index 5ce143c25..674b0ef8d 100644 --- a/website/source/api/secret/aws/index.html.md +++ b/website/source/api/secret/aws/index.html.md @@ -226,6 +226,10 @@ updated with the new attributes. on the role, then this default TTL will be used. Valid only when `credential_type` is one of `assumed_role` or `federation_token`. +- `max_sts_ttl` `(string)` - The max allowed TTL for STS credentials (credentials + TTL are capped to `max_sts_ttl`). Valid only when `credential_type` is one of + `assumed_role` or `federation_token`. + Legacy parameters: These parameters are supported for backwards compatibility only. They cannot be diff --git a/website/source/docs/auth/gcp.html.md b/website/source/docs/auth/gcp.html.md index b6b95edd0..d0f735b99 100644 --- a/website/source/docs/auth/gcp.html.md +++ b/website/source/docs/auth/gcp.html.md @@ -258,9 +258,9 @@ curl \ #### gcloud Example ```text -gcloud beta iam service-accounts sign-jwt credentials.json - \ - --iam-account=service-account@my-project.iam.gserviceaccount.com \ - --project=my-project +$ gcloud beta iam service-accounts sign-jwt credentials.json - \ + --iam-account=service-account@my-project.iam.gserviceaccount.com \ + --project=my-project ``` #### Golang Example diff --git a/website/source/docs/secrets/gcp/index.html.md b/website/source/docs/secrets/gcp/index.html.md index 99ac6c0f9..a7867d05c 100644 --- a/website/source/docs/secrets/gcp/index.html.md +++ b/website/source/docs/secrets/gcp/index.html.md @@ -62,7 +62,7 @@ management tool. If you are running Vault from inside [Google Compute Engine][gce] or [Google Kubernetes Engine][gke], the instance or pod service account can be used in - place or specifying the credentials JSON file. + place or specifying the credentials JSON file. For more information on authentication, see the [authentication section](#authentication) below. 1. Configure a roleset. Rolesets determine the permissions that Service Account @@ -94,9 +94,9 @@ credentials generated by Vault will have on GCP resources. } EOF ``` - - Alternatively, provide a file for the `bindings` argument like so: - + + Alternatively, provide a file for the `bindings` argument like so: + ```text $ vault write gcp/roleset/my-roleset bindings=@mybindings.hcl @@ -121,21 +121,21 @@ was configured, you can generate OAuth2 tokens or service account keys. To generate OAuth2 tokens, read from `gcp/token/...`. The roleset must have been created as type `access_token`: - ```text - $ vault read gcp/token/my-token-roleset - - Key Value - --- ----- - expires_at_seconds 1537402548 - token ya29.c.ElodBmNPwHUNY5gcBpnXcE4ywG4w1k... - token_ttl 3599 - ``` +```text +$ vault read gcp/token/my-token-roleset + +Key Value +--- ----- +expires_at_seconds 1537402548 +token ya29.c.ElodBmNPwHUNY5gcBpnXcE4ywG4w1k... +token_ttl 3599 +``` This endpoint generates a non-renewable, non-revocable static OAuth2 access token -with a lifetime of one hour, where `token_ttl` is given in seconds and the -`expires_at_seconds` is the expiry time for the token, given as a Unix timestamp. -The `token` value then can be used as a HTTP Authorization Bearer token in requests -to GCP APIs: +with a lifetime of one hour, where `token_ttl` is given in seconds and the +`expires_at_seconds` is the expiry time for the token, given as a Unix timestamp. +The `token` value then can be used as a HTTP Authorization Bearer token in requests +to GCP APIs: ```sh $ curl -H "Authorization: Bearer ya29.c.ElodBmNPwHUNY5gcBpnXcE4ywG4w1k..." @@ -345,7 +345,7 @@ Advantages of `access_tokens`: Disadvantages of `access_tokens`: * Cannot be used with some client libraries or tools -* Have a static life-time of 1 hr that cannot be modified, revoked, or extended. +* Have a static life-time of 1 hr that cannot be modified, revoked, or extended. Advantages of `service_account_keys`: * Controllable life-time through Vault, allowing for longer access @@ -353,7 +353,7 @@ Advantages of `service_account_keys`: Disadvantages of `service_account_keys`: * Infinite lifetime in GCP (i.e. if they are not managed properly, leaked keys can live forever) -* Limited to 10 per roleset/service account. +* Limited to 10 per roleset/service account. When generating OAuth access tokens, Vault will still generate a dedicated service account and key. This private key is stored in Vault @@ -457,7 +457,7 @@ for more details. ## Upgrade Guides -### Deprecation of Access Token Leases +### Deprecation of Access Token Leases ~> **NOTE**: This only affects access tokens. There is no change to the `service_account_key` secret type