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

acl: add token expiration and ACL role functionality #14320

Merged
merged 25 commits into from
Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
08845ce
server: add ACL token expiration config parameters. (#13667)
jrasell Jul 12, 2022
8981c5a
core: add ACL token expiry state, struct, and RPC handling. (#13718)
jrasell Jul 13, 2022
ee2e7d1
acl: add token expiry checking to ACL token resolution. (#13756)
jrasell Jul 15, 2022
14bcc74
core: add expired token garbage collection periodic jobs. (#13805)
jrasell Jul 19, 2022
add4ea9
acl: enable configuration and visualisation of token expiration for u…
jrasell Jul 20, 2022
892ab8a
Merge branch 'main' into f-gh-13120-sso-umbrella
jrasell Aug 2, 2022
d6a9c14
core: add ACL role state schema and functionality. (#13955)
jrasell Aug 9, 2022
4efb82a
rpc: add ACL Role RPC endpoint for CRUD actions.
jrasell Aug 11, 2022
fafc100
http: add ACL Role HTTP endpoints for CRUD actions.
jrasell Aug 11, 2022
3826b1f
api: add ACL Role API implementation for CRUD actions.
jrasell Aug 11, 2022
b8fe43a
Merge pull request #14057 from hashicorp/f-gh-13120-acl-role-rpc-endp…
jrasell Aug 11, 2022
ff798dc
cli: add new acl role subcommands for CRUD role actions. (#14087)
jrasell Aug 12, 2022
6a26bda
core: add ACL role functionality to ACL tokens.
jrasell Aug 17, 2022
9e69124
api: add ACL role linking to ACL tokens.
jrasell Aug 17, 2022
9953159
cli: add ability to create and view tokens with ACL role links.
jrasell Aug 17, 2022
37a4c32
Merge pull request #14110 from hashicorp/f-gh-13120-acl-role-token-su…
jrasell Aug 17, 2022
f2effdc
acl: add replication to ACL Roles from authoritative region. (#14176)
jrasell Aug 22, 2022
4be6de2
acl: make listing RPC and HTTP API a stub return object. (#14211)
jrasell Aug 22, 2022
f4db3b6
acl: allow tokens to lookup linked roles. (#14227)
jrasell Aug 24, 2022
34a1591
cli: output none when a token has no expiration.
jrasell Aug 24, 2022
f0b24d1
cli: use policy flag for role creation and update.
jrasell Aug 24, 2022
69d6961
acl: fix a bug where roles could be duplicated by name.
jrasell Aug 25, 2022
b2483ed
Merge pull request #14291 from hashicorp/f-gh-13120-sso-various-small…
jrasell Aug 25, 2022
7b3bd10
Merge branch 'main' into f-gh-13120-sso-umbrella-merged-main
jrasell Aug 25, 2022
bf46203
Merge branch 'main' into f-gh-13120-sso-umbrella-merged-main
jrasell Aug 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
224 changes: 211 additions & 13 deletions api/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,96 @@ func (a *ACLTokens) ExchangeOneTimeToken(secret string, q *WriteOptions) (*ACLTo
return resp.Token, wm, nil
}

var (
// errMissingACLRoleID is the generic errors to use when a call is missing
// the required ACL Role ID parameter.
errMissingACLRoleID = errors.New("missing ACL role ID")
)

// ACLRoles is used to query the ACL Role endpoints.
type ACLRoles struct {
client *Client
}

// ACLRoles returns a new handle on the ACL roles API client.
func (c *Client) ACLRoles() *ACLRoles {
return &ACLRoles{client: c}
}

// List is used to detail all the ACL roles currently stored within state.
func (a *ACLRoles) List(q *QueryOptions) ([]*ACLRoleListStub, *QueryMeta, error) {
var resp []*ACLRoleListStub
qm, err := a.client.query("/v1/acl/roles", &resp, q)
if err != nil {
return nil, nil, err
}
return resp, qm, nil
}

// Create is used to create an ACL role.
func (a *ACLRoles) Create(role *ACLRole, w *WriteOptions) (*ACLRole, *WriteMeta, error) {
if role.ID != "" {
return nil, nil, errors.New("cannot specify ACL role ID")
}
var resp ACLRole
wm, err := a.client.write("/v1/acl/role", role, &resp, w)
if err != nil {
return nil, nil, err
}
return &resp, wm, nil
}

// Update is used to update an existing ACL role.
func (a *ACLRoles) Update(role *ACLRole, w *WriteOptions) (*ACLRole, *WriteMeta, error) {
if role.ID == "" {
return nil, nil, errMissingACLRoleID
}
var resp ACLRole
wm, err := a.client.write("/v1/acl/role/"+role.ID, role, &resp, w)
if err != nil {
return nil, nil, err
}
return &resp, wm, nil
}

// Delete is used to delete an ACL role.
func (a *ACLRoles) Delete(roleID string, w *WriteOptions) (*WriteMeta, error) {
if roleID == "" {
return nil, errMissingACLRoleID
}
wm, err := a.client.delete("/v1/acl/role/"+roleID, nil, nil, w)
if err != nil {
return nil, err
}
return wm, nil
}

// Get is used to look up an ACL role.
func (a *ACLRoles) Get(roleID string, q *QueryOptions) (*ACLRole, *QueryMeta, error) {
if roleID == "" {
return nil, nil, errMissingACLRoleID
}
var resp ACLRole
qm, err := a.client.query("/v1/acl/role/"+roleID, &resp, q)
if err != nil {
return nil, nil, err
}
return &resp, qm, nil
}

// GetByName is used to look up an ACL role using its name.
func (a *ACLRoles) GetByName(roleName string, q *QueryOptions) (*ACLRole, *QueryMeta, error) {
if roleName == "" {
return nil, nil, errors.New("missing ACL role name")
}
var resp ACLRole
qm, err := a.client.query("/v1/acl/role/name/"+roleName, &resp, q)
if err != nil {
return nil, nil, err
}
return &resp, qm, nil
}

// ACLPolicyListStub is used to for listing ACL policies
type ACLPolicyListStub struct {
Name string
Expand Down Expand Up @@ -231,24 +321,62 @@ type JobACL struct {

// ACLToken represents a client token which is used to Authenticate
type ACLToken struct {
AccessorID string
SecretID string
Name string
Type string
Policies []string
Global bool
CreateTime time.Time
AccessorID string
SecretID string
Name string
Type string
Policies []string

// Roles represents the ACL roles that this token is tied to. The token
// will inherit the permissions of all policies detailed within the role.
Roles []*ACLTokenRoleLink

Global bool
CreateTime time.Time

// ExpirationTime represents the point after which a token should be
// considered revoked and is eligible for destruction. The zero value of
// time.Time does not respect json omitempty directives, so we must use a
// pointer.
ExpirationTime *time.Time `json:",omitempty"`

// ExpirationTTL is a convenience field for helping set ExpirationTime to a
// value of CreateTime+ExpirationTTL. This can only be set during token
// creation. This is a string version of a time.Duration like "2m".
ExpirationTTL time.Duration `json:",omitempty"`

CreateIndex uint64
ModifyIndex uint64
}

// ACLTokenRoleLink is used to link an ACL token to an ACL role. The ACL token
// can therefore inherit all the ACL policy permissions that the ACL role
// contains.
type ACLTokenRoleLink struct {

// ID is the ACLRole.ID UUID. This field is immutable and represents the
// absolute truth for the link.
ID string

// Name is the human friendly identifier for the ACL role and is a
// convenience field for operators.
Name string
}

type ACLTokenListStub struct {
AccessorID string
Name string
Type string
Policies []string
Global bool
CreateTime time.Time
AccessorID string
Name string
Type string
Policies []string
Roles []*ACLTokenRoleLink
Global bool
CreateTime time.Time

// ExpirationTime represents the point after which a token should be
// considered revoked and is eligible for destruction. A nil value
// indicates no expiration has been set on the token.
ExpirationTime *time.Time `json:"expiration_time,omitempty"`

CreateIndex uint64
ModifyIndex uint64
}
Expand Down Expand Up @@ -277,3 +405,73 @@ type OneTimeTokenExchangeResponse struct {
type BootstrapRequest struct {
BootstrapSecret string
}

// ACLRole is an abstraction for the ACL system which allows the grouping of
// ACL policies into a single object. ACL tokens can be created and linked to
// a role; the token then inherits all the permissions granted by the policies.
type ACLRole struct {

// ID is an internally generated UUID for this role and is controlled by
// Nomad. It can be used after role creation to update the existing role.
ID string

// Name is unique across the entire set of federated clusters and is
// supplied by the operator on role creation. The name can be modified by
// updating the role and including the Nomad generated ID. This update will
// not affect tokens created and linked to this role. This is a required
// field.
Name string

// Description is a human-readable, operator set description that can
// provide additional context about the role. This is an optional field.
Description string

// Policies is an array of ACL policy links. Although currently policies
// can only be linked using their name, in the future we will want to add
// IDs also and thus allow operators to specify either a name, an ID, or
// both. At least one entry is required.
Policies []*ACLRolePolicyLink

CreateIndex uint64
ModifyIndex uint64
}

// ACLRolePolicyLink is used to link a policy to an ACL role. We use a struct
// rather than a list of strings as in the future we will want to add IDs to
// policies and then link via these.
type ACLRolePolicyLink struct {

// Name is the ACLPolicy.Name value which will be linked to the ACL role.
Name string
}

// ACLRoleListStub is the stub object returned when performing a listing of ACL
// roles. While it might not currently be different to the full response
// object, it allows us to future-proof the RPC in the event the ACLRole object
// grows over time.
type ACLRoleListStub struct {

// ID is an internally generated UUID for this role and is controlled by
// Nomad.
ID string

// Name is unique across the entire set of federated clusters and is
// supplied by the operator on role creation. The name can be modified by
// updating the role and including the Nomad generated ID. This update will
// not affect tokens created and linked to this role. This is a required
// field.
Name string

// Description is a human-readable, operator set description that can
// provide additional context about the role. This is an operational field.
Description string

// Policies is an array of ACL policy links. Although currently policies
// can only be linked using their name, in the future we will want to add
// IDs also and thus allow operators to specify either a name, an ID, or
// both.
Policies []*ACLRolePolicyLink

CreateIndex uint64
ModifyIndex uint64
}
Loading