Add no-default-policy flag and API parameter to allow exclusion of the
default policy from a token create command.
This commit is contained in:
parent
d6693129de
commit
1a45696208
|
@ -25,7 +25,9 @@ FEATURES:
|
||||||
which allows a token to retrieve its own information, and `revoke-self` and
|
which allows a token to retrieve its own information, and `revoke-self` and
|
||||||
`renew-self`, which are self-explanatory. If your existing Vault
|
`renew-self`, which are self-explanatory. If your existing Vault
|
||||||
installation contains a policy called `default`, it will not be overridden,
|
installation contains a policy called `default`, it will not be overridden,
|
||||||
but it will be added to each new token created. [GH-732]
|
but it will be added to each new token created. You can override this
|
||||||
|
behavior when using manual token creation (i.e. not via an authentication
|
||||||
|
backend) by setting the "no_default_policy" flag to true. [GH-732]
|
||||||
|
|
||||||
IMPROVEMENTS:
|
IMPROVEMENTS:
|
||||||
|
|
||||||
|
|
|
@ -117,12 +117,13 @@ func (c *TokenAuth) RevokeTree(token string) error {
|
||||||
|
|
||||||
// TokenCreateRequest is the options structure for creating a token.
|
// TokenCreateRequest is the options structure for creating a token.
|
||||||
type TokenCreateRequest struct {
|
type TokenCreateRequest struct {
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
Policies []string `json:"policies,omitempty"`
|
Policies []string `json:"policies,omitempty"`
|
||||||
Metadata map[string]string `json:"meta,omitempty"`
|
Metadata map[string]string `json:"meta,omitempty"`
|
||||||
Lease string `json:"lease,omitempty"`
|
Lease string `json:"lease,omitempty"`
|
||||||
TTL string `json:"ttl,omitempty"`
|
TTL string `json:"ttl,omitempty"`
|
||||||
NoParent bool `json:"no_parent,omitempty"`
|
NoParent bool `json:"no_parent,omitempty"`
|
||||||
DisplayName string `json:"display_name"`
|
NoDefaultPolicy bool `json:"no_default_policy,omitempty"`
|
||||||
NumUses int `json:"num_uses"`
|
DisplayName string `json:"display_name"`
|
||||||
|
NumUses int `json:"num_uses"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ type TokenCreateCommand struct {
|
||||||
func (c *TokenCreateCommand) Run(args []string) int {
|
func (c *TokenCreateCommand) Run(args []string) int {
|
||||||
var format string
|
var format string
|
||||||
var id, displayName, lease, ttl string
|
var id, displayName, lease, ttl string
|
||||||
var orphan bool
|
var orphan, noDefaultPolicy bool
|
||||||
var metadata map[string]string
|
var metadata map[string]string
|
||||||
var numUses int
|
var numUses int
|
||||||
var policies []string
|
var policies []string
|
||||||
|
@ -28,6 +28,7 @@ func (c *TokenCreateCommand) Run(args []string) int {
|
||||||
flags.StringVar(&lease, "lease", "", "")
|
flags.StringVar(&lease, "lease", "", "")
|
||||||
flags.StringVar(&ttl, "ttl", "", "")
|
flags.StringVar(&ttl, "ttl", "", "")
|
||||||
flags.BoolVar(&orphan, "orphan", false, "")
|
flags.BoolVar(&orphan, "orphan", false, "")
|
||||||
|
flags.BoolVar(&noDefaultPolicy, "no-default-policy", false, "")
|
||||||
flags.IntVar(&numUses, "use-limit", 0, "")
|
flags.IntVar(&numUses, "use-limit", 0, "")
|
||||||
flags.Var((*kvFlag.Flag)(&metadata), "metadata", "")
|
flags.Var((*kvFlag.Flag)(&metadata), "metadata", "")
|
||||||
flags.Var((*sliceflag.StringFlag)(&policies), "policy", "")
|
flags.Var((*sliceflag.StringFlag)(&policies), "policy", "")
|
||||||
|
@ -55,13 +56,14 @@ func (c *TokenCreateCommand) Run(args []string) int {
|
||||||
ttl = lease
|
ttl = lease
|
||||||
}
|
}
|
||||||
secret, err := client.Auth().Token().Create(&api.TokenCreateRequest{
|
secret, err := client.Auth().Token().Create(&api.TokenCreateRequest{
|
||||||
ID: id,
|
ID: id,
|
||||||
Policies: policies,
|
Policies: policies,
|
||||||
Metadata: metadata,
|
Metadata: metadata,
|
||||||
TTL: ttl,
|
TTL: ttl,
|
||||||
NoParent: orphan,
|
NoParent: orphan,
|
||||||
DisplayName: displayName,
|
NoDefaultPolicy: noDefaultPolicy,
|
||||||
NumUses: numUses,
|
DisplayName: displayName,
|
||||||
|
NumUses: numUses,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -122,6 +124,9 @@ Token Options:
|
||||||
root tokens can create orphan tokens. This prevents
|
root tokens can create orphan tokens. This prevents
|
||||||
the new token from being revoked with your token.
|
the new token from being revoked with your token.
|
||||||
|
|
||||||
|
-no-default-policy If specified, the token will not have the "default"
|
||||||
|
policy included in its policy set.
|
||||||
|
|
||||||
-policy="name" Policy to associate with this token. This can be
|
-policy="name" Policy to associate with this token. This can be
|
||||||
specified multiple times.
|
specified multiple times.
|
||||||
|
|
||||||
|
|
|
@ -1036,6 +1036,45 @@ func TestCore_HandleRequest_CreateToken_Lease(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that we handle excluding the default policy
|
||||||
|
func TestCore_HandleRequest_CreateToken_NoDefaultPolicy(t *testing.T) {
|
||||||
|
c, _, root := TestCoreUnsealed(t)
|
||||||
|
|
||||||
|
// Create a new credential
|
||||||
|
req := logical.TestRequest(t, logical.WriteOperation, "auth/token/create")
|
||||||
|
req.ClientToken = root
|
||||||
|
req.Data["policies"] = []string{"foo"}
|
||||||
|
req.Data["no_default_policy"] = true
|
||||||
|
resp, err := c.HandleRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure we got a new client token back
|
||||||
|
clientToken := resp.Auth.ClientToken
|
||||||
|
if clientToken == "" {
|
||||||
|
t.Fatalf("bad: %#v", resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the policy and metadata
|
||||||
|
te, err := c.tokenStore.Lookup(clientToken)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
expect := &TokenEntry{
|
||||||
|
ID: clientToken,
|
||||||
|
Parent: root,
|
||||||
|
Policies: []string{"foo"},
|
||||||
|
Path: "auth/token/create",
|
||||||
|
DisplayName: "token",
|
||||||
|
CreationTime: te.CreationTime,
|
||||||
|
TTL: time.Hour * 24 * 30,
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(te, expect) {
|
||||||
|
t.Fatalf("Bad: %#v expect: %#v", te, expect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCore_LimitedUseToken(t *testing.T) {
|
func TestCore_LimitedUseToken(t *testing.T) {
|
||||||
c, _, root := TestCoreUnsealed(t)
|
c, _, root := TestCoreUnsealed(t)
|
||||||
|
|
||||||
|
|
|
@ -547,14 +547,15 @@ func (ts *TokenStore) handleCreateCommon(
|
||||||
|
|
||||||
// Read and parse the fields
|
// Read and parse the fields
|
||||||
var data struct {
|
var data struct {
|
||||||
ID string
|
ID string
|
||||||
Policies []string
|
Policies []string
|
||||||
Metadata map[string]string `mapstructure:"meta"`
|
Metadata map[string]string `mapstructure:"meta"`
|
||||||
NoParent bool `mapstructure:"no_parent"`
|
NoParent bool `mapstructure:"no_parent"`
|
||||||
Lease string
|
NoDefaultPolicy bool `mapstructure:"no_default_policy"`
|
||||||
TTL string
|
Lease string
|
||||||
DisplayName string `mapstructure:"display_name"`
|
TTL string
|
||||||
NumUses int `mapstructure:"num_uses"`
|
DisplayName string `mapstructure:"display_name"`
|
||||||
|
NumUses int `mapstructure:"num_uses"`
|
||||||
}
|
}
|
||||||
if err := mapstructure.WeakDecode(req.Data, &data); err != nil {
|
if err := mapstructure.WeakDecode(req.Data, &data); err != nil {
|
||||||
return logical.ErrorResponse(fmt.Sprintf(
|
return logical.ErrorResponse(fmt.Sprintf(
|
||||||
|
@ -602,7 +603,7 @@ func (ts *TokenStore) handleCreateCommon(
|
||||||
return logical.ErrorResponse("child policies must be subset of parent"), logical.ErrInvalidRequest
|
return logical.ErrorResponse("child policies must be subset of parent"), logical.ErrInvalidRequest
|
||||||
}
|
}
|
||||||
te.Policies = data.Policies
|
te.Policies = data.Policies
|
||||||
if !strListSubset(te.Policies, []string{"root"}) {
|
if !strListSubset(te.Policies, []string{"root"}) && !data.NoDefaultPolicy {
|
||||||
te.Policies = append(te.Policies, "default")
|
te.Policies = append(te.Policies, "default")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -888,7 +888,7 @@ func TestTokenStore_HandleRequest_Lookup(t *testing.T) {
|
||||||
|
|
||||||
exp = map[string]interface{}{
|
exp = map[string]interface{}{
|
||||||
"id": "client",
|
"id": "client",
|
||||||
"policies": []string{"foo"},
|
"policies": []string{"foo", "default"},
|
||||||
"path": "auth/token/create",
|
"path": "auth/token/create",
|
||||||
"meta": map[string]string(nil),
|
"meta": map[string]string(nil),
|
||||||
"display_name": "token",
|
"display_name": "token",
|
||||||
|
|
|
@ -87,6 +87,12 @@ of the header should be "X-Vault-Token" and the value should be the token.
|
||||||
If true and set by a root caller, the token will not have the
|
If true and set by a root caller, the token will not have the
|
||||||
parent token of the caller. This creates a token with no parent.
|
parent token of the caller. This creates a token with no parent.
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<span class="param">no_default_profile</span>
|
||||||
|
<span class="param-flags">optional</span>
|
||||||
|
If true the `default` profile will not be a part of this token's
|
||||||
|
policy set.
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="param">lease</span>
|
<span class="param">lease</span>
|
||||||
<span class="param-flags">optional</span>
|
<span class="param-flags">optional</span>
|
||||||
|
|
Loading…
Reference in New Issue