acl: oss plumbing to support auth method namespace rules in enterprise (#7794)

This includes website docs updates.
This commit is contained in:
R.B. Boyer 2020-05-06 13:48:04 -05:00 committed by GitHub
parent b730590c82
commit 1187d7288e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 118 additions and 11 deletions

View File

@ -2123,10 +2123,15 @@ func (a *ACL) AuthMethodSet(args *structs.ACLAuthMethodSetRequest, reply *struct
// Instantiate a validator but do not cache it yet. This will validate the
// configuration.
if _, err := authmethod.NewValidator(a.srv.logger, method); err != nil {
validator, err := authmethod.NewValidator(a.srv.logger, method)
if err != nil {
return fmt.Errorf("Invalid Auth Method: %v", err)
}
if err := enterpriseAuthMethodValidation(method, validator); err != nil {
return err
}
if err := a.srv.fsm.State().ACLAuthMethodUpsertValidateEnterprise(method, existing); err != nil {
return err
}
@ -2301,7 +2306,10 @@ func (a *ACL) Login(args *structs.ACLLoginRequest, reply *structs.ACLToken) erro
}
// This always will return a valid pointer
targetMeta := method.TargetEnterpriseMeta(verifiedIdentity.EnterpriseMeta)
targetMeta, err := computeTargetEnterpriseMeta(method, verifiedIdentity)
if err != nil {
return err
}
// 3. send map through role bindings
serviceIdentities, roleLinks, err := a.srv.evaluateRoleBindings(validator, verifiedIdentity, &auth.EnterpriseMeta, targetMeta)

View File

@ -0,0 +1,19 @@
// +build !consulent
package consul
import (
"github.com/hashicorp/consul/agent/consul/authmethod"
"github.com/hashicorp/consul/agent/structs"
)
func enterpriseAuthMethodValidation(method *structs.ACLAuthMethod, validator authmethod.Validator) error {
return nil
}
func computeTargetEnterpriseMeta(
method *structs.ACLAuthMethod,
verifiedIdentity *authmethod.Identity,
) (*structs.EnterpriseMeta, error) {
return method.TargetEnterpriseMeta(verifiedIdentity.EnterpriseMeta), nil
}

View File

@ -5087,6 +5087,7 @@ func TestACLEndpoint_Login_with_MaxTokenTTL(t *testing.T) {
got.SecretID = ""
got.Hash = nil
defaultEntMeta := structs.DefaultEnterpriseMeta()
expect := &structs.ACLToken{
AuthMethod: method.Name,
Description: `token created via login: {"pod":"pod1"}`,
@ -5096,7 +5097,9 @@ func TestACLEndpoint_Login_with_MaxTokenTTL(t *testing.T) {
ServiceIdentities: []*structs.ACLServiceIdentity{
{ServiceName: "web"},
},
EnterpriseMeta: *defaultEntMeta,
}
expect.ACLAuthMethodEnterpriseMeta.FillWithEnterpriseMeta(defaultEntMeta)
require.Equal(t, got, expect)
}

View File

@ -6,6 +6,10 @@ import "github.com/hashicorp/consul/agent/structs"
type enterpriseConfig struct{}
func enterpriseValidation(method *structs.ACLAuthMethod, config *Config) error {
return nil
}
func (v *Validator) k8sEntMetaFromFields(fields map[string]string) *structs.EnterpriseMeta {
return nil
}

View File

@ -1060,6 +1060,8 @@ type ACLAuthMethod struct {
// Embedded Enterprise ACL Meta
EnterpriseMeta `mapstructure:",squash"`
ACLAuthMethodEnterpriseFields `mapstructure:",squash"`
// Embedded Raft Metadata
RaftIndex `hash:"ignore"`
}

View File

@ -28,6 +28,8 @@ node_prefix "" {
}`
)
type ACLAuthMethodEnterpriseFields struct{}
type ACLAuthMethodEnterpriseMeta struct{}
func (_ *ACLAuthMethodEnterpriseMeta) FillWithEnterpriseMeta(_ *EnterpriseMeta) {

View File

@ -195,6 +195,10 @@ type ACLAuthMethod struct {
CreateIndex uint64
ModifyIndex uint64
// NamespaceRules apply only on auth methods defined in the default namespace.
// Namespacing is a Consul Enterprise feature.
NamespaceRules []*ACLAuthMethodNamespaceRule `json:",omitempty"`
// Namespace is the namespace the ACLAuthMethod is associated with.
// Namespacing is a Consul Enterprise feature.
Namespace string `json:",omitempty"`
@ -237,6 +241,18 @@ func (m *ACLAuthMethod) UnmarshalJSON(data []byte) error {
return nil
}
type ACLAuthMethodNamespaceRule struct {
// Selector is an expression that matches against verified identity
// attributes returned from the auth method during login.
Selector string `json:",omitempty"`
// BindNamespace is the target namespace of the binding. Can be lightly
// templated using HIL ${foo} syntax from available field names.
//
// If empty it's created in the same namespace as the auth method.
BindNamespace string `json:",omitempty"`
}
type ACLAuthMethodListEntry struct {
Name string
Type string

View File

@ -70,6 +70,31 @@ The table below shows this endpoint's support for
If not provided at all, the namespace will be inherited from the request's ACL
token or will default to the `default` namespace. Added in Consul 1.7.0.
- `NamespaceRules` `(array<NamespaceRule>)` <EnterpriseAlert inline /> - A set
of rules that can control which namespace tokens created via this auth method
will be created within. Note that assigning namespaces via rules requires the
auth method to reside within the `default` namespace. Unlike binding rules,
the **first** matching namespace rule wins. Added in Consul 1.8.0.
- `Selector` `(string: "")` - Specifies the expression used to match this
namespace rule against valid identities returned from an auth method
validation. If empty this namespace rule matches all valid identities
returned from the auth method. For example:
```text
serviceaccount.namespace==default and serviceaccount.name!=vault
```
- `BindNamespace` `(string: <required>)` - If the namespace rule's `Selector`
matches then this is used to control the namespace where the token is
created. This can either be a plain string or lightly templated
using [HIL syntax](https://github.com/hashicorp/hil) to interpolate the
same values that are usable by the `Selector` syntax. For example:
```text
prefixed-${serviceaccount.name}
```
### Sample Payload
```json
@ -218,6 +243,31 @@ The table below shows this endpoint's support for
If not provided at all, the namespace will be inherited from the request's ACL
token or will default to the `default` namespace. Added in Consul 1.7.0.
- `NamespaceRules` `(array<NamespaceRule>)` <EnterpriseAlert inline /> - A set
of rules that can control which namespace tokens created via this auth method
will be created within. Note that assigning namespaces via rules requires the
auth method to reside within the `default` namespace. Unlike binding rules,
the **first** matching namespace rule wins. Added in Consul 1.8.0.
- `Selector` `(string: "")` - Specifies the expression used to match this
namespace rule against valid identities returned from an auth method
validation. If empty this namespace rule matches all valid identities
returned from the auth method. For example:
```text
serviceaccount.namespace==default and serviceaccount.name!=vault
```
- `BindNamespace` `(string: <required>)` - If the namespace rule's `Selector`
matches then this is used to control the namespace where the token is
created. This can either be a plain string or lightly templated
using [HIL syntax](https://github.com/hashicorp/hil) to interpolate the
same values that are usable by the `Selector` syntax. For example:
```text
prefixed-${serviceaccount.name}
```
### Sample Payload
```json

View File

@ -37,17 +37,20 @@ parameters are required to properly configure an auth method of type
([JWT](https://jwt.io/ 'JSON Web Token')) used by the Consul leader to
validate application JWTs during login.
- `MapNamespaces` `(bool: <false>)` <EnterpriseAlert inline /> - Indicates whether
the auth method should attempt to map the Kubernetes namespace to a Consul
- `MapNamespaces` `(bool: <false>)` <EnterpriseAlert inline /> -
**Deprecated in Consul 1.8.0 in favor of [namespace rules](/api/acl/auth-methods#namespacerules).**
Indicates whether the auth method should attempt to map the Kubernetes namespace to a Consul
namespace instead of creating tokens in the auth methods own namespace. Note
that mapping namespaces requires the auth method to reside within the
`default` namespace.
- `ConsulNamespacePrefix` `(string: <optional>)` <EnterpriseAlert inline /> - When
`MapNamespaces` is enabled, this value will be prefixed to the Kubernetes
- `ConsulNamespacePrefix` `(string: <optional>)` <EnterpriseAlert inline /> -
**Deprecated in Consul 1.8.0 in favor of [namespace rules](/api/acl/auth-methods#namespacerules).**
When `MapNamespaces` is enabled, this value will be prefixed to the Kubernetes
namespace to determine the Consul namespace to create the new token within.
- `ConsulNamespaceOverrides` `(map: <string:string>)` <EnterpriseAlert inline /> -
**Deprecated in Consul 1.8.0 in favor of [namespace rules](/api/acl/auth-methods#namespacerules).**
This field is a mapping of Kubernetes namespace names to Consul namespace
names. If a Kubernetes namespace is present within this map, the value will
be used without adding the `ConsulNamespacePrefix`. If the value in the map
@ -133,11 +136,11 @@ roleRef:
The authentication step returns the following trusted identity attributes for
use in binding rule selectors and bind name interpolation.
| Attributes | Supported Selector Operations | Can be Interpolated |
| -------------------------- | ----------------------------- | ------------------- |
| `serviceaccount.namespace` | Equal, Not Equal | yes |
| `serviceaccount.name` | Equal, Not Equal | yes |
| `serviceaccount.uid` | Equal, Not Equal | yes |
| Attributes | Supported Selector Operations | Can be Interpolated |
| -------------------------- | -------------------------------------------------- | ------------------- |
| `serviceaccount.namespace` | Equal, Not Equal, In, Not In, Matches, Not Matches | yes |
| `serviceaccount.name` | Equal, Not Equal, In, Not In, Matches, Not Matches | yes |
| `serviceaccount.uid` | Equal, Not Equal, In, Not In, Matches, Not Matches | yes |
## Kubernetes Authentication Details