secret/aws: Using roles instead of policy

This commit is contained in:
Armon Dadgar 2015-04-27 14:20:28 -07:00
parent 5edf8cf3a8
commit 434305a6c2
5 changed files with 53 additions and 50 deletions

View file

@ -26,7 +26,7 @@ func Backend() *framework.Backend {
Paths: []*framework.Path{
pathConfigRoot(),
pathConfigLease(&b),
pathPolicy(),
pathRoles(),
pathUser(&b),
},
@ -52,5 +52,5 @@ are automatically revoked at the end of the lease.
After mounting this backend, credentials to generate IAM keys must
be configured with the "root" path and policies must be written using
the "policy/" endpoints before any access keys can be generated.
the "roles/" endpoints before any access keys can be generated.
`

View file

@ -76,7 +76,7 @@ func testAccStepConfig(t *testing.T) logicaltest.TestStep {
func testAccStepReadUser(t *testing.T, name string) logicaltest.TestStep {
return logicaltest.TestStep{
Operation: logical.ReadOperation,
Path: name,
Path: "creds/" + name,
Check: func(resp *logical.Response) error {
var d struct {
AccessKey string `mapstructure:"access_key"`
@ -109,7 +109,7 @@ func testAccStepReadUser(t *testing.T, name string) logicaltest.TestStep {
func testAccStepWritePolicy(t *testing.T, name string, policy string) logicaltest.TestStep {
return logicaltest.TestStep{
Operation: logical.WriteOperation,
Path: "policy/" + name,
Path: "roles/" + name,
Data: map[string]interface{}{
"policy": testPolicy,
},
@ -119,14 +119,14 @@ func testAccStepWritePolicy(t *testing.T, name string, policy string) logicaltes
func testAccStepDeletePolicy(t *testing.T, n string) logicaltest.TestStep {
return logicaltest.TestStep{
Operation: logical.DeleteOperation,
Path: "policy/" + n,
Path: "roles/" + n,
}
}
func testAccStepReadPolicy(t *testing.T, name string, value string) logicaltest.TestStep {
return logicaltest.TestStep{
Operation: logical.ReadOperation,
Path: "policy/" + name,
Path: "roles/" + name,
Check: func(resp *logical.Response) error {
if resp == nil {
if value == "" {

View file

@ -9,9 +9,9 @@ import (
"github.com/hashicorp/vault/logical/framework"
)
func pathPolicy() *framework.Path {
func pathRoles() *framework.Path {
return &framework.Path{
Pattern: `policy/(?P<name>\w+)`,
Pattern: `roles/(?P<name>\w+)`,
Fields: map[string]*framework.FieldSchema{
"name": &framework.FieldSchema{
Type: framework.TypeString,
@ -25,17 +25,17 @@ func pathPolicy() *framework.Path {
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.DeleteOperation: pathPolicyDelete,
logical.ReadOperation: pathPolicyRead,
logical.WriteOperation: pathPolicyWrite,
logical.DeleteOperation: pathRolesDelete,
logical.ReadOperation: pathRolesRead,
logical.WriteOperation: pathRolesWrite,
},
HelpSynopsis: pathPolicyHelpSyn,
HelpDescription: pathPolicyHelpDesc,
HelpSynopsis: pathRolesHelpSyn,
HelpDescription: pathRolesHelpDesc,
}
}
func pathPolicyDelete(
func pathRolesDelete(
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
err := req.Storage.Delete("policy/" + d.Get("name").(string))
if err != nil {
@ -45,7 +45,7 @@ func pathPolicyDelete(
return nil, nil
}
func pathPolicyRead(
func pathRolesRead(
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
entry, err := req.Storage.Get("policy/" + d.Get("name").(string))
if err != nil {
@ -62,7 +62,7 @@ func pathPolicyRead(
}, nil
}
func pathPolicyWrite(
func pathRolesWrite(
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
var buf bytes.Buffer
if err := json.Compact(&buf, []byte(d.Get("policy").(string))); err != nil {
@ -82,16 +82,16 @@ func pathPolicyWrite(
return nil, nil
}
const pathPolicyHelpSyn = `
const pathRolesHelpSyn = `
Read and write IAM policies that access keys can be made for.
`
const pathPolicyHelpDesc = `
This path allows you to read and write policies that are used to
create access keys. These policies map directly to the route to read the
const pathRolesHelpDesc = `
This path allows you to read and write roles that are used to
create access keys. These roles have IAM policies that map directly to the route to read the
access keys. For example, if the backend is mounted at "aws" and you
wrote a policy to "aws/policy/deploy" then a user could request access
credentials at "aws/deploy".
create a role at "aws/roles/deploy" then a user could request access
credentials at "aws/creds/deploy".
The policies written are normal IAM policies. Vault will not attempt to
parse these except to validate that they're basic JSON. To validate the

View file

@ -12,11 +12,11 @@ import (
func pathUser(b *backend) *framework.Path {
return &framework.Path{
Pattern: `(?P<name>\w+)`,
Pattern: `creds/(?P<name>\w+)`,
Fields: map[string]*framework.FieldSchema{
"name": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Name of the policy",
Description: "Name of the role",
},
},
@ -36,11 +36,11 @@ func (b *backend) pathUserRead(
// Read the policy
policy, err := req.Storage.Get("policy/" + policyName)
if err != nil {
return nil, fmt.Errorf("error retrieving policy: %s", err)
return nil, fmt.Errorf("error retrieving role: %s", err)
}
if policy == nil {
return logical.ErrorResponse(fmt.Sprintf(
"Policy '%s' not found", policyName)), nil
"Role '%s' not found", policyName)), nil
}
// Use the helper to create the secret
@ -138,14 +138,14 @@ type walUser struct {
}
const pathUserHelpSyn = `
Generate an access key pair for a specific policy.
Generate an access key pair for a specific role.
`
const pathUserHelpDesc = `
This path will generate a new, never before used key pair for
accessing AWS. The IAM policy used to back this key pair will be
the "name" parameter. For example, if this backend is mounted at "aws",
then "aws/deploy" would generate access keys for the "deploy" policy.
then "aws/creds/deploy" would generate access keys for the "deploy" role.
The access keys will have a lease associated with them. The access keys
can be revoked by using the lease ID.

View file

@ -20,14 +20,15 @@ on every path, use `vault help` after mounting the backend.
## Quick Start
Mount the aws secret backend using the `vault mount` command:
The first step to using the aws backend is to mount it.
Unlike the `generic` backend, the `aws` backend is not mounted by default.
```text
$ vault mount aws
Successfully mounted 'aws' at 'aws'!
```
Configure the root credentials that are used to manage IAM credentials:
Next, we must configure the root credentials that are used to manage IAM credentials:
```text
$ vault write aws/config/root \
@ -44,17 +45,19 @@ The following parameters are required:
credentials.
- `region` the AWS region for API calls.
Create an IAM policy:
The next step is to configure a role. A role is a logical name that maps
to a policy used to generated those credentials. For example, lets create
a "deploy" role:
```text
$ vault write aws/policy/deploy \
$ vault write aws/roles/deploy \
name=deploy \
policy=@policy.json
```
This path will generate a new, never before used key pair for
accessing AWS. The IAM policy used to back this key pair will be
the "name" parameter, which is "deploy" in this example.
This path will create a named role along with the IAM policy used
to restrict permissions for it. This is used to dynamically create
a new pair of IAM credentials when needed.
The `@` tells Vault to load the policy from the file named `policy.json`. Here
is an example IAM policy to get started:
@ -73,12 +76,12 @@ is an example IAM policy to get started:
For more information on IAM policies, please see the
[AWS IAM policy documentation](http://docs.aws.amazon.com/IAM/latest/UserGuide/PoliciesOverview.html).
Vault can now generate IAM credentials under the given policy:
To generate a new set of IAM credentials, we simply read from that role:
```text
$ vault read aws/deploy
$ vault read aws/creds/deploy
Key Value
lease_id aws/deploy/7cb8df71-782f-3de1-79dd-251778e49f58
lease_id aws/creds/deploy/7cb8df71-782f-3de1-79dd-251778e49f58
lease_duration 3600
access_key AKIAIOMYUTSLGJOGLHTQ
secret_key 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
@ -87,9 +90,9 @@ secret_key BK9++oBABaBvRKcT5KEF69xQGcH7ZpPRF3oqVEv7
If you run the command again, you will get a new set of credentials:
```text
$ vault read aws/deploy
$ vault read aws/creds/deploy
Key Value
lease_id aws/deploy/82d89562-ff19-382e-6be9-cb45c8f6a42d
lease_id aws/creds/deploy/82d89562-ff19-382e-6be9-cb45c8f6a42d
lease_duration 3600
access_key AKIAJZ5YRPHFH3QHRRRQ
secret_key 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
@ -183,20 +186,20 @@ interactive help output.
</dd>
</dl>
### /aws/policy/
### /aws/roles/
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Creates or updates a named policy.
Creates or updates a named role.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/aws/policy/<name>`</dd>
<dd>`/aws/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
@ -220,14 +223,14 @@ interactive help output.
<dl class="api">
<dt>Description</dt>
<dd>
Queries a named policy.
Queries a named role.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/aws/policy/<name>`</dd>
<dd>`/aws/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
@ -253,14 +256,14 @@ interactive help output.
<dl class="api">
<dt>Description</dt>
<dd>
Deletes a named policy.
Deletes a named role.
</dd>
<dt>Method</dt>
<dd>DELETE</dd>
<dt>URL</dt>
<dd>`/aws/policy/<name>`</dd>
<dd>`/aws/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
@ -274,20 +277,20 @@ interactive help output.
</dl>
### /aws/
### /aws/creds/
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Generates a dynamic IAM credential based on the named policy.
Generates a dynamic IAM credential based on the named role.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/aws/<name>`</dd>
<dd>`/aws/creds/<name>`</dd>
<dt>Parameters</dt>
<dd>