-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
[VAULT-1986] Cap AWS Token TTL based on Default Lease TTL #12026
Changes from 2 commits
0691a83
72c8f66
d26ae96
fee1233
bc46727
72162c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -892,9 +892,11 @@ func (b *backend) pathRoleCreateUpdate(ctx context.Context, req *logical.Request | |
defaultLeaseTTL := b.System().DefaultLeaseTTL() | ||
systemMaxTTL := b.System().MaxLeaseTTL() | ||
if roleEntry.TokenTTL > defaultLeaseTTL { | ||
roleEntry.TokenTTL = defaultLeaseTTL | ||
resp.AddWarning(fmt.Sprintf("Given ttl of %d seconds greater than current mount/system default of %d seconds; ttl will be capped at login time", roleEntry.TokenTTL/time.Second, defaultLeaseTTL/time.Second)) | ||
} | ||
if roleEntry.TokenMaxTTL > systemMaxTTL { | ||
roleEntry.TokenMaxTTL = systemMaxTTL | ||
resp.AddWarning(fmt.Sprintf("Given max ttl of %d seconds greater than current mount/system default of %d seconds; max ttl will be capped at login time", roleEntry.TokenMaxTTL/time.Second, systemMaxTTL/time.Second)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Is this now slightly inaccurate? I believe if you read the config back for the role, it will probably have stored the system max TTL instead of the specified max TTL right? So it's actually already been capped. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, we should remove the about "at login". We're now setting this on the role. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't think that this is the case because we're not actually modifying/overriding |
||
} | ||
if roleEntry.TokenMaxTTL != 0 && roleEntry.TokenMaxTTL < roleEntry.TokenTTL { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ import ( | |
"reflect" | ||
"strings" | ||
"testing" | ||
"time" | ||
|
||
"github.com/go-test/deep" | ||
"github.com/hashicorp/go-hclog" | ||
|
@@ -762,16 +763,112 @@ func TestAwsEc2_RoleDurationSeconds(t *testing.T) { | |
} | ||
|
||
if resp.Data["ttl"].(int64) != 10 { | ||
t.Fatalf("bad: period; expected: 10, actual: %d", resp.Data["ttl"]) | ||
t.Fatalf("bad: ttl; expected: 10, actual: %d", resp.Data["ttl"]) | ||
} | ||
if resp.Data["max_ttl"].(int64) != 20 { | ||
t.Fatalf("bad: period; expected: 20, actual: %d", resp.Data["max_ttl"]) | ||
t.Fatalf("bad: max_ttl; expected: 20, actual: %d", resp.Data["max_ttl"]) | ||
} | ||
if resp.Data["period"].(int64) != 30 { | ||
t.Fatalf("bad: period; expected: 30, actual: %d", resp.Data["period"]) | ||
} | ||
} | ||
|
||
func TestAwsIam_RoleDurationSeconds(t *testing.T) { | ||
config := logical.TestBackendConfig() | ||
storage := &logical.InmemStorage{} | ||
config.StorageView = storage | ||
|
||
b, err := Backend(config) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
err = b.Setup(context.Background(), config) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
roleData := map[string]interface{}{ | ||
"auth_type": "iam", | ||
"bound_iam_principal_arn": "arn:aws:iam::123456789012:role/testrole", | ||
"resolve_aws_unique_ids": false, | ||
"ttl": "20m", | ||
"max_ttl": "30m", | ||
} | ||
|
||
roleReq := &logical.Request{ | ||
Operation: logical.CreateOperation, | ||
Storage: storage, | ||
Path: "role/testrole", | ||
Data: roleData, | ||
} | ||
|
||
resp, err := b.HandleRequest(context.Background(), roleReq) | ||
if err != nil || (resp != nil && resp.IsError()) { | ||
t.Fatalf("resp: %#v, err: %v", resp, err) | ||
} | ||
|
||
roleReq.Operation = logical.ReadOperation | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: It does make the tests more verbose, but I think as a general rule it's nice to treat structs as immutable in tests so that the definition of your requests is always fully defined near the call site, and you reduce the risk of surprising bugs from dependencies between parts of the test. |
||
|
||
resp, err = b.HandleRequest(context.Background(), roleReq) | ||
if err != nil || (resp != nil && resp.IsError()) { | ||
t.Fatalf("resp: %#v, err: %v", resp, err) | ||
} | ||
|
||
// since default lease TTL for system is 24hr, Token TTL should not be capped | ||
// since max lease TTL for system is 48hr, Token Max TTL should not be capped | ||
if resp.Data["token_ttl"].(int64) != 1200 { | ||
t.Fatalf("bad: token_ttl; expected: 1200, actual: %d", resp.Data["ttl"]) | ||
} | ||
if resp.Data["max_ttl"].(int64) != 1800 { | ||
t.Fatalf("bad: max_ttl; expected: 1800, actual: %d", resp.Data["max_ttl"]) | ||
} | ||
|
||
// set default lease TTL to 10m; Token TTL should be capped at 10m | ||
// set max lease TTL to 20m; Token Max TTL should be capped at 20m | ||
config = &logical.BackendConfig{ | ||
Logger: logging.NewVaultLogger(hclog.Trace), | ||
|
||
System: &logical.StaticSystemView{ | ||
DefaultLeaseTTLVal: time.Minute * 10, | ||
MaxLeaseTTLVal: time.Minute * 20, | ||
}, | ||
StorageView: &logical.InmemStorage{}, | ||
} | ||
|
||
b, err = Backend(config) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
err = b.Setup(context.Background(), config) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
roleReq.Operation = logical.CreateOperation | ||
|
||
resp, err = b.HandleRequest(context.Background(), roleReq) | ||
if err != nil || (resp != nil && resp.IsError()) { | ||
t.Fatalf("resp: %#v, err: %v", resp, err) | ||
} | ||
|
||
roleReq.Operation = logical.ReadOperation | ||
|
||
resp, err = b.HandleRequest(context.Background(), roleReq) | ||
if err != nil || (resp != nil && resp.IsError()) { | ||
t.Fatalf("resp: %#v, err: %v", resp, err) | ||
} | ||
|
||
if resp.Data["token_ttl"].(int64) != 600 { | ||
t.Fatalf("bad: token_ttl; expected: 600, actual: %d", resp.Data["ttl"]) | ||
} | ||
|
||
if resp.Data["token_max_ttl"].(int64) != 1200 { | ||
t.Fatalf("bad: token_max_ttl; expected: 1200, actual: %d", resp.Data["ttl"]) | ||
} | ||
} | ||
|
||
func TestRoleEntryUpgradeV(t *testing.T) { | ||
config := logical.TestBackendConfig() | ||
storage := &logical.InmemStorage{} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
```release-note:bug | ||
auth/aws: Fix a bug where the Token TTL for AWS is not capped by Default Lease TTL. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this still true? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forgot about that, fixed now :) |
||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come we clamp TTL to at most the default? I would only expect clamping to be needed for max. Is
.DefaultLeaseTTL()
just a poorly named function?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function is correctly named, but this is existing behavior within the plugin that was never actually implemented. We can either remove it and only cap on max, or implement the original intent. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, personally I would err towards removing the warning rather than adding capping - it's the more correct and safer change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Tom's recommendation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jasonodonnell what do you mean by never implemented? The value from
b.System().DefaultLeaseTTL()
is determined by this method:vault/vault/dynamic_system_view.go
Lines 124 to 127 in 2e0dcb7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sync'ed up with Vinay on this and it turns out that TTL calculation caps the max TTL but doesn't care about the
ttl
(ortoken_ttl
) value as long as that's under the max. I'm fine with removing this. At some point we were capping the default but then removed it when we changed things to use tokenutil.