Skip to content
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

Add fields 'ttl' and 'num_uses' to SecretID generation. #14474

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
3e0e7a8
Add fields 'ttl' and 'num_uses' to SecretID generation.
RemcoBuddelmeijer Mar 12, 2022
8aeca35
Add secret_id_num_uses response field to generating SecretID
RemcoBuddelmeijer Mar 12, 2022
491e879
Add tests for new ttl and num_uses SecretID generation fields
RemcoBuddelmeijer Mar 12, 2022
44cfaab
Patch up test for ttl and num_uses fields
RemcoBuddelmeijer Mar 12, 2022
0f1c941
Add changelog entry for auth/approle 'ttl' and 'num_uses' fields
RemcoBuddelmeijer Mar 12, 2022
689e8c6
Add fields to API Docs and AppRole Auth Docs example
RemcoBuddelmeijer Mar 14, 2022
6b33aeb
Correct error message for failing test on missing field.
RemcoBuddelmeijer Apr 8, 2022
bd138f9
Remove unnecessary int cast to int "secret_id_num_uses" field.
RemcoBuddelmeijer Apr 8, 2022
00d8c0d
Move numUses field check to after assignment.
RemcoBuddelmeijer Apr 8, 2022
f72834e
Remove metadata entry in sample payload to limit change to changes made.
RemcoBuddelmeijer Apr 8, 2022
645e480
Bind fields 'ttl' and 'num_uses' to role's configuration.
RemcoBuddelmeijer May 31, 2022
0e6902a
Merge branch 'hashicorp:main' into feature/numuses-and-ttl-appsecret
RemcoBuddelmeijer May 31, 2022
772adde
Update changelog 14474 with a more detailed description.
RemcoBuddelmeijer May 31, 2022
59a7fed
Elaborate more on the bounds of the 'ttl' and 'num_uses' field.
RemcoBuddelmeijer May 31, 2022
5c2f6b5
Upper bound ttl with role secret id ttl
RemcoBuddelmeijer Jun 3, 2022
cba46ac
Formatting issues. Removed unnecessary newline
Jun 3, 2022
e4c9bfe
Update documentation for AppRole Secret ID and Role
RemcoBuddelmeijer Jun 3, 2022
d01dc76
Cleanup approle secret ID test and impl
RemcoBuddelmeijer Jun 3, 2022
ad0b5a5
Define ttl and num_uses in every test
RemcoBuddelmeijer Jun 3, 2022
364f714
Rename test RoleSecretID -> RoleSecretIDWithoutFields
RemcoBuddelmeijer Jun 3, 2022
376040b
Test secret id generation defaults to Role's config
RemcoBuddelmeijer Jun 23, 2022
dfc5b45
Change finit -> finite
RemcoBuddelmeijer Jun 23, 2022
ee219ec
Rephrase comments to the correct validation check
RemcoBuddelmeijer Jun 23, 2022
700e77d
Rephrase role-secret-id option description
RemcoBuddelmeijer Jun 30, 2022
5f34b69
Remove "default" incorrect statement about ttl
RemcoBuddelmeijer Jun 30, 2022
a9b4fac
Remove "default" incorrect statement about ttl for custom secret id
RemcoBuddelmeijer Jun 30, 2022
0f32504
Touch up approle.mdx to align more with path_role documentation
RemcoBuddelmeijer Jun 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions builtin/credential/approle/path_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -2382,6 +2382,11 @@ func (b *backend) handleRoleSecretIDCommon(ctx context.Context, req *logical.Req
if numUses < 0 {
return logical.ErrorResponse("num_uses cannot be negative"), nil
}

// If the role's secret_id_num_uses is lower than the specified num_uses, throw an error rather than implicitly overriding
if numUses > role.SecretIDNumUses {
return logical.ErrorResponse("num_uses cannot be higher than the role's secret_id_num_uses"), nil
}
} else {
numUses = role.SecretIDNumUses
}
Expand All @@ -2390,6 +2395,10 @@ func (b *backend) handleRoleSecretIDCommon(ctx context.Context, req *logical.Req
// Check whether or not ttl is defined, otherwise fallback to secret_id_ttl
if ttlRaw, ok := data.GetOk("ttl"); ok {
ttl = time.Second * time.Duration(ttlRaw.(int))
// If the ttl is less than the role's secret_id_ttl, throw an error rather than implicitly overriding
if ttl < role.SecretIDTTL {
return logical.ErrorResponse("ttl cannot be shorter than the role's secret_id_ttl"), nil
}
} else {
ttl = role.SecretIDTTL
}
Expand Down
79 changes: 74 additions & 5 deletions builtin/credential/approle/path_role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1141,7 +1141,6 @@ func TestAppRole_RoleSecretID(t *testing.T) {
"secret_id": "abcd123",
}
roleSecretIDReq.Data = roleCustomSecretIDData
roleSecretIDReq.Operation = logical.UpdateOperation
resp, err = b.HandleRequest(context.Background(), roleSecretIDReq)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%v resp:%#v", err, resp)
Expand All @@ -1152,15 +1151,15 @@ func TestAppRole_RoleSecretID(t *testing.T) {
}
}

func TestAppRole_RoleSecretIDWithFields(t *testing.T) {
func TestAppRole_RoleSecretIDWithValidFields(t *testing.T) {
var resp *logical.Response
var err error
b, storage := createBackendWithStorage(t)

roleData := map[string]interface{}{
"policies": "p,q,r,s",
"secret_id_num_uses": 0,
"secret_id_ttl": 0,
"secret_id_num_uses": 5,
"secret_id_ttl": 5,
"token_ttl": 400,
"token_max_ttl": 500,
}
Expand Down Expand Up @@ -1206,7 +1205,6 @@ func TestAppRole_RoleSecretIDWithFields(t *testing.T) {
roleCustomSecretIDData["secret_id"] = "abcd123"

roleSecretIDReq.Data = roleCustomSecretIDData
roleSecretIDReq.Operation = logical.UpdateOperation
resp, err = b.HandleRequest(context.Background(), roleSecretIDReq)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%v resp:%#v", err, resp)
Expand All @@ -1223,6 +1221,77 @@ func TestAppRole_RoleSecretIDWithFields(t *testing.T) {
}
}

func TestAppRole_ErrorsRoleSecretIDWithInvalidFields(t *testing.T) {
var resp *logical.Response
var err error
b, storage := createBackendWithStorage(t)

roleData := map[string]interface{}{
"policies": "p,q,r,s",
"secret_id_num_uses": 1,
"secret_id_ttl": 1,
"token_ttl": 400,
"token_max_ttl": 500,
}
roleReq := &logical.Request{
Operation: logical.CreateOperation,
Path: "role/role1",
Storage: storage,
Data: roleData,
}

resp, err = b.HandleRequest(context.Background(), roleReq)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%v resp:%#v", err, resp)
}

type testCase struct {
name string
payload map[string]interface{}
expected string
}

testCases := []testCase{
{
name: "invalid 'ttl' field",
payload: map[string]interface{}{"secret_id": "abcd123", "ttl": 0},
expected: "ttl cannot be shorter than the role's secret_id_ttl",
},
{
name: "invalid 'num_uses' field",
payload: map[string]interface{}{"secret_id": "abcd123", "num_uses": 2},
expected: "num_uses cannot be higher than the role's secret_id_num_uses",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
roleSecretIDReq := &logical.Request{
Operation: logical.UpdateOperation,
Path: "role/role1/secret-id",
Storage: storage,
}
roleSecretIDReq.Data = tc.payload
resp, err = b.HandleRequest(context.Background(), roleSecretIDReq)
if err != nil || (resp != nil && !resp.IsError()) {
t.Fatalf("err:%v resp:%#v", err, resp)
}
if resp.Data["error"].(string) != tc.expected {
t.Fatalf("expected: %q, got: %q", tc.expected, resp.Data["error"].(string))
}

roleSecretIDReq.Path = "role/role1/custom-secret-id"
resp, err = b.HandleRequest(context.Background(), roleSecretIDReq)
if err != nil || (resp != nil && !resp.IsError()) {
t.Fatalf("err:%v resp:%#v", err, resp)
}
if resp.Data["error"].(string) != tc.expected {
t.Fatalf("expected: %q, got: %q", tc.expected, resp.Data["error"].(string))
}
})
}
}

func TestAppRole_RoleCRUD(t *testing.T) {
var resp *logical.Response
var err error
Expand Down