diff --git a/api/authtokens/authtoken_test.go b/api/authtokens/authtoken_test.go index 4efa22ec6..adbd884a1 100644 --- a/api/authtokens/authtoken_test.go +++ b/api/authtokens/authtoken_test.go @@ -45,7 +45,7 @@ func TestList(t *testing.T) { role, err = rolesClient.AddPrincipals(tc.Context(), role.Item.Id, 0, []string{"u_anon"}, roles.WithAutomaticVersioning(true)) require.NoError(err) require.NotNil(role) - role, err = rolesClient.AddGrants(tc.Context(), role.Item.Id, 0, []string{"type=auth-method;actions=authenticate"}, roles.WithAutomaticVersioning(true)) + role, err = rolesClient.AddGrants(tc.Context(), role.Item.Id, 0, []string{"id=*;type=auth-method;actions=authenticate"}, roles.WithAutomaticVersioning(true)) require.NoError(err) require.NotNil(role) diff --git a/internal/db/migrations/postgres.gen.go b/internal/db/migrations/postgres.gen.go index 519f6a57b..57f4abe14 100644 --- a/internal/db/migrations/postgres.gen.go +++ b/internal/db/migrations/postgres.gen.go @@ -1103,8 +1103,8 @@ insert into iam_role (public_id, name, description, scope_id) values('r_default', 'Default Grants', 'Default role created on first instantiation of Boundary. It is meant to provide enough permissions for users to successfully authenticate via various client types.', 'global'); insert into iam_role_grant (role_id, canonical_grant, raw_grant) values - ('r_default', 'type=scope;actions=list', 'type=scope;actions=list'), - ('r_default', 'type=auth-method;actions=authenticate,list', 'type=auth-method;actions=authenticate,list'); + ('r_default', 'id=*;type=scope;actions=list', 'id=*;type=scope;actions=list'), + ('r_default', 'id=*;type=auth-method;actions=authenticate,list', 'id=*;type=auth-method;actions=authenticate,list'); insert into iam_user_role (role_id, principal_id) values ('r_default', 'u_anon'); diff --git a/internal/db/migrations/postgres/06_iam.up.sql b/internal/db/migrations/postgres/06_iam.up.sql index 50d423d35..bca7d4813 100644 --- a/internal/db/migrations/postgres/06_iam.up.sql +++ b/internal/db/migrations/postgres/06_iam.up.sql @@ -585,8 +585,8 @@ insert into iam_role (public_id, name, description, scope_id) values('r_default', 'Default Grants', 'Default role created on first instantiation of Boundary. It is meant to provide enough permissions for users to successfully authenticate via various client types.', 'global'); insert into iam_role_grant (role_id, canonical_grant, raw_grant) values - ('r_default', 'type=scope;actions=list', 'type=scope;actions=list'), - ('r_default', 'type=auth-method;actions=authenticate,list', 'type=auth-method;actions=authenticate,list'); + ('r_default', 'id=*;type=scope;actions=list', 'id=*;type=scope;actions=list'), + ('r_default', 'id=*;type=auth-method;actions=authenticate,list', 'id=*;type=auth-method;actions=authenticate,list'); insert into iam_user_role (role_id, principal_id) values ('r_default', 'u_anon'); diff --git a/internal/iam/repository_scope.go b/internal/iam/repository_scope.go index ab76d6a1e..0d4a50a3a 100644 --- a/internal/iam/repository_scope.go +++ b/internal/iam/repository_scope.go @@ -279,13 +279,13 @@ func (r *Repository) CreateScope(ctx context.Context, s *Scope, userId string, o // Grants { grants := []interface{}{} - roleGrant, err := NewRoleGrant(defaultRolePublicId, "type=scope;actions=list") + roleGrant, err := NewRoleGrant(defaultRolePublicId, "id=*;type=scope;actions=list") if err != nil { return fmt.Errorf("unable to create in memory role grant: %w", err) } grants = append(grants, roleGrant) - roleGrant, err = NewRoleGrant(defaultRolePublicId, "type=auth-method;actions=authenticate,list") + roleGrant, err = NewRoleGrant(defaultRolePublicId, "id=*;type=auth-method;actions=authenticate,list") if err != nil { return fmt.Errorf("unable to create in memory role grant: %w", err) } diff --git a/internal/perms/acl.go b/internal/perms/acl.go index e323f152a..0a061e242 100644 --- a/internal/perms/acl.go +++ b/internal/perms/acl.go @@ -8,7 +8,7 @@ speaking of which: TODO: put that chart in public docs. Anyways, from that page you can see that there are really only a few patterns of ACLs that are ever allowed: -* type=;actions= +* id=*;type=;actions= * id=;actions= * id=;type=;actions= @@ -81,21 +81,23 @@ func (a ACL) Allowed(r Resource, aType action.Type) (results ACLResults) { continue } switch { - // type=;actions= - case grant.id == "" && - grant.typ == r.Type: + // id=*;type=;actions= + case grant.id == "*" && + (grant.typ == r.Type || grant.typ == resource.All): results.Allowed = true return // id=;actions= - case (grant.id == r.Id || grant.id == "*") && + case grant.id != "" && + (grant.id == r.Id || grant.id == "*") && grant.typ == resource.Unknown: results.Allowed = true return // id=;type=;actions= - case grant.id == r.Pin && - grant.typ == r.Type: + case grant.id != "" && + grant.id == r.Pin && + (grant.typ == r.Type || grant.typ == resource.All): results.Allowed = true return } diff --git a/internal/perms/acl_test.go b/internal/perms/acl_test.go index e1151a91a..6afff7996 100644 --- a/internal/perms/acl_test.go +++ b/internal/perms/acl_test.go @@ -35,14 +35,14 @@ func Test_ACLAllowed(t *testing.T) { grants: []string{ "id=a_bar;actions=read,update", "id=a_foo;type=host-catalog;actions=update,delete", - "type=host-set;actions=list,create", + "id=*;type=host-set;actions=list,create", }, }, { scope: "o_b", grants: []string{ - "type=host-set;actions=list,create", - "type=host;actions=*", + "id=*;type=host-set;actions=list,create", + "id=*;type=host;actions=*", "id=*;actions=authenticate", }, }, @@ -52,6 +52,12 @@ func Test_ACLAllowed(t *testing.T) { "id={{user.id }};actions=create,update", }, }, + { + scope: "o_d", + grants: []string{ + "id=*;type=*;actions=create,update", + }, + }, } // See acl.go for expected allowed formats. The goal here is to basically @@ -203,6 +209,16 @@ func Test_ACLAllowed(t *testing.T) { }, userId: "u_abcd1234", }, + { + name: "all type", + resource: Resource{ScopeId: "o_d", Type: resource.Account}, + scopeGrants: commonGrants, + actionsAllowed: []actionAllowed{ + {action: action.Create, allowed: true}, + {action: action.Update, allowed: true}, + }, + userId: "u_abcd1234", + }, } for _, test := range tests { diff --git a/internal/perms/grants.go b/internal/perms/grants.go index ce5d6d664..42a5802a3 100644 --- a/internal/perms/grants.go +++ b/internal/perms/grants.go @@ -279,8 +279,8 @@ func Parse(scopeId, userId, grantString string) (Grant, error) { } } - if grant.id == "" && grant.typ == resource.Unknown { - return Grant{}, errors.New(`"id" and "type" cannot both be empty`) + if grant.id == "" { + return Grant{}, errors.New(`"id" cannot be empty, perhaps "*" was meant`) } if err := grant.validateType(); err != nil { diff --git a/internal/perms/grants_test.go b/internal/perms/grants_test.go index 8e48ef4e8..84773a928 100644 --- a/internal/perms/grants_test.go +++ b/internal/perms/grants_test.go @@ -349,7 +349,7 @@ func Test_Parse(t *testing.T) { { name: "empty id and type", input: "actions=create", - err: `"id" and "type" cannot both be empty`, + err: `"id" cannot be empty, perhaps "*" was meant`, }, { name: "good json",