mirror of
https://github.com/hashicorp/vault.git
synced 2026-04-28 09:39:39 -04:00
updating azure auth plugin and docs (#4975)
This commit is contained in:
parent
ecc622ac43
commit
3ba265cf6a
6 changed files with 105 additions and 26 deletions
13
vendor/github.com/hashicorp/vault-plugin-auth-azure/azure.go
generated
vendored
13
vendor/github.com/hashicorp/vault-plugin-auth-azure/azure.go
generated
vendored
|
|
@ -24,6 +24,10 @@ type computeClient interface {
|
|||
Get(ctx context.Context, resourceGroup, vmName string, instanceView compute.InstanceViewTypes) (compute.VirtualMachine, error)
|
||||
}
|
||||
|
||||
type vmssClient interface {
|
||||
Get(ctx context.Context, resourceGroup, vmssName string) (compute.VirtualMachineScaleSet, error)
|
||||
}
|
||||
|
||||
type tokenVerifier interface {
|
||||
Verify(ctx context.Context, token string) (*oidc.IDToken, error)
|
||||
}
|
||||
|
|
@ -31,6 +35,7 @@ type tokenVerifier interface {
|
|||
type provider interface {
|
||||
Verifier() tokenVerifier
|
||||
ComputeClient(subscriptionID string) computeClient
|
||||
VMSSClient(subscriptionID string) vmssClient
|
||||
}
|
||||
|
||||
type azureProvider struct {
|
||||
|
|
@ -134,6 +139,14 @@ func (p *azureProvider) ComputeClient(subscriptionID string) computeClient {
|
|||
return client
|
||||
}
|
||||
|
||||
func (p *azureProvider) VMSSClient(subscriptionID string) vmssClient {
|
||||
client := compute.NewVirtualMachineScaleSetsClient(subscriptionID)
|
||||
client.Authorizer = p.authorizer
|
||||
client.Sender = p.httpClient
|
||||
client.AddToUserAgent(userAgent())
|
||||
return client
|
||||
}
|
||||
|
||||
type azureSettings struct {
|
||||
TenantID string
|
||||
ClientID string
|
||||
|
|
|
|||
4
vendor/github.com/hashicorp/vault-plugin-auth-azure/path_config.go
generated
vendored
4
vendor/github.com/hashicorp/vault-plugin-auth-azure/path_config.go
generated
vendored
|
|
@ -59,15 +59,15 @@ type azureConfig struct {
|
|||
}
|
||||
|
||||
func (b *azureAuthBackend) config(ctx context.Context, s logical.Storage) (*azureConfig, error) {
|
||||
config := new(azureConfig)
|
||||
entry, err := s.Get(ctx, "config")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if entry == nil {
|
||||
return config, nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
config := new(azureConfig)
|
||||
if err := entry.DecodeJSON(config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
89
vendor/github.com/hashicorp/vault-plugin-auth-azure/path_login.go
generated
vendored
89
vendor/github.com/hashicorp/vault-plugin-auth-azure/path_login.go
generated
vendored
|
|
@ -35,7 +35,11 @@ func pathLogin(b *azureAuthBackend) *framework.Path {
|
|||
},
|
||||
"vm_name": &framework.FieldSchema{
|
||||
Type: framework.TypeString,
|
||||
Description: `The name of the virtual machine.`,
|
||||
Description: `The name of the virtual machine. This value is ignored if vmss_name is specified.`,
|
||||
},
|
||||
"vmss_name": &framework.FieldSchema{
|
||||
Type: framework.TypeString,
|
||||
Description: `The name of the virtual machine scale set the instance is in.`,
|
||||
},
|
||||
},
|
||||
|
||||
|
|
@ -60,12 +64,16 @@ func (b *azureAuthBackend) pathLogin(ctx context.Context, req *logical.Request,
|
|||
}
|
||||
subscriptionID := data.Get("subscription_id").(string)
|
||||
resourceGroupName := data.Get("resource_group_name").(string)
|
||||
vmssName := data.Get("vmss_name").(string)
|
||||
vmName := data.Get("vm_name").(string)
|
||||
|
||||
config, err := b.config(ctx, req.Storage)
|
||||
if err != nil {
|
||||
return nil, errwrap.Wrapf("unable to retrieve backend configuration: {{err}}", err)
|
||||
}
|
||||
if config == nil {
|
||||
config = new(azureConfig)
|
||||
}
|
||||
|
||||
role, err := b.role(ctx, req.Storage, roleName)
|
||||
if err != nil {
|
||||
|
|
@ -75,7 +83,6 @@ func (b *azureAuthBackend) pathLogin(ctx context.Context, req *logical.Request,
|
|||
return logical.ErrorResponse(fmt.Sprintf("invalid role name %q", roleName)), nil
|
||||
}
|
||||
|
||||
// Set the client id for 'aud' claim verification
|
||||
provider, err := b.getProvider(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -98,7 +105,7 @@ func (b *azureAuthBackend) pathLogin(ctx context.Context, req *logical.Request,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err := b.verifyResource(ctx, subscriptionID, resourceGroupName, vmName, claims, role); err != nil {
|
||||
if err := b.verifyResource(ctx, subscriptionID, resourceGroupName, vmName, vmssName, claims, role); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
@ -168,30 +175,72 @@ func (b *azureAuthBackend) verifyClaims(claims *additionalClaims, role *azureRol
|
|||
return nil
|
||||
}
|
||||
|
||||
func (b *azureAuthBackend) verifyResource(ctx context.Context, subscriptionID, resourceGroupName, vmName string, claims *additionalClaims, role *azureRole) error {
|
||||
func (b *azureAuthBackend) verifyResource(ctx context.Context, subscriptionID, resourceGroupName, vmName string, vmssName string, claims *additionalClaims, role *azureRole) error {
|
||||
// If not checking anything with the resource id, exit early
|
||||
if len(role.BoundResourceGroups) == 0 && len(role.BoundSubscriptionsIDs) == 0 && len(role.BoundLocations) == 0 {
|
||||
if len(role.BoundResourceGroups) == 0 && len(role.BoundSubscriptionsIDs) == 0 && len(role.BoundLocations) == 0 && len(role.BoundScaleSets) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if subscriptionID == "" || resourceGroupName == "" || vmName == "" {
|
||||
return errors.New("subscription_id, resource_group_name, and vm_name are required")
|
||||
if subscriptionID == "" || resourceGroupName == "" {
|
||||
return errors.New("subscription_id and resource_group_name are required")
|
||||
}
|
||||
|
||||
client := b.provider.ComputeClient(subscriptionID)
|
||||
vm, err := client.Get(ctx, resourceGroupName, vmName, compute.InstanceView)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("unable to retrieve virtual machine metadata: {{err}}", err)
|
||||
var principalID, location *string
|
||||
|
||||
switch {
|
||||
// If vmss name is specified, the vm name will be ignored and only the scale set
|
||||
// will be verified since vm names are generated automatically for scale sets
|
||||
case vmssName != "":
|
||||
client := b.provider.VMSSClient(subscriptionID)
|
||||
vmss, err := client.Get(ctx, resourceGroupName, vmssName)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("unable to retrieve virtual machine scale set metadata: {{err}}", err)
|
||||
}
|
||||
|
||||
if vmss.Identity == nil {
|
||||
return errors.New("vmss client did not return identity information")
|
||||
}
|
||||
if vmss.Identity.PrincipalID == nil {
|
||||
return errors.New("vmss principal id is empty")
|
||||
}
|
||||
|
||||
// Check bound scale sets
|
||||
if len(role.BoundScaleSets) > 0 && !strListContains(role.BoundScaleSets, vmssName) {
|
||||
return errors.New("scale set not authorized")
|
||||
}
|
||||
|
||||
principalID = vmss.Identity.PrincipalID
|
||||
location = vmss.Location
|
||||
|
||||
case vmName != "":
|
||||
client := b.provider.ComputeClient(subscriptionID)
|
||||
vm, err := client.Get(ctx, resourceGroupName, vmName, compute.InstanceView)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("unable to retrieve virtual machine metadata: {{err}}", err)
|
||||
}
|
||||
|
||||
if vm.Identity == nil {
|
||||
return errors.New("vm client did not return identity information")
|
||||
}
|
||||
|
||||
if vm.Identity.PrincipalID == nil {
|
||||
return errors.New("vm principal id is empty")
|
||||
}
|
||||
|
||||
// Check bound scale sets
|
||||
if len(role.BoundScaleSets) > 0 {
|
||||
return errors.New("bound scale set defined but this vm isn't in a scale set")
|
||||
}
|
||||
|
||||
principalID = vm.Identity.PrincipalID
|
||||
location = vm.Location
|
||||
|
||||
default:
|
||||
return errors.New("either vm_name or vmss_name is required")
|
||||
}
|
||||
|
||||
// Ensure the principal id for the VM matches the verified token OID
|
||||
if vm.Identity == nil {
|
||||
return errors.New("vm client did not return identity information")
|
||||
}
|
||||
if vm.Identity.PrincipalID == nil {
|
||||
return errors.New("vm principal id is empty")
|
||||
}
|
||||
if to.String(vm.Identity.PrincipalID) != claims.ObjectID {
|
||||
if to.String(principalID) != claims.ObjectID {
|
||||
return errors.New("token object id does not match virtual machine principal id")
|
||||
}
|
||||
|
||||
|
|
@ -207,10 +256,10 @@ func (b *azureAuthBackend) verifyResource(ctx context.Context, subscriptionID, r
|
|||
|
||||
// Check bound locations
|
||||
if len(role.BoundLocations) > 0 {
|
||||
if vm.Location == nil {
|
||||
if location == nil {
|
||||
return errors.New("vm location is empty")
|
||||
}
|
||||
if !strListContains(role.BoundLocations, to.String(vm.Location)) {
|
||||
if !strListContains(role.BoundLocations, to.String(location)) {
|
||||
return errors.New("location not authorized")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
14
vendor/github.com/hashicorp/vault-plugin-auth-azure/path_role.go
generated
vendored
14
vendor/github.com/hashicorp/vault-plugin-auth-azure/path_role.go
generated
vendored
|
|
@ -79,6 +79,11 @@ is restricted to.`,
|
|||
"bound_locations": &framework.FieldSchema{
|
||||
Type: framework.TypeCommaStringSlice,
|
||||
Description: `Comma-separated list of locations that login
|
||||
is restricted to.`,
|
||||
},
|
||||
"bound_scale_sets": &framework.FieldSchema{
|
||||
Type: framework.TypeCommaStringSlice,
|
||||
Description: `Comma-separated list of scale sets that login
|
||||
is restricted to.`,
|
||||
},
|
||||
},
|
||||
|
|
@ -121,6 +126,7 @@ type azureRole struct {
|
|||
BoundResourceGroups []string `json:"bound_resource_groups"`
|
||||
BoundSubscriptionsIDs []string `json:"bound_subscription_ids"`
|
||||
BoundLocations []string `json:"bound_locations"`
|
||||
BoundScaleSets []string `json:"bound_scale_sets"`
|
||||
}
|
||||
|
||||
// role takes a storage backend and the name and returns the role's storage
|
||||
|
|
@ -193,6 +199,7 @@ func (b *azureAuthBackend) pathRoleRead(ctx context.Context, req *logical.Reques
|
|||
"bound_subscription_ids": role.BoundSubscriptionsIDs,
|
||||
"bound_resource_groups": role.BoundResourceGroups,
|
||||
"bound_locations": role.BoundLocations,
|
||||
"bound_scale_sets": role.BoundScaleSets,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -291,11 +298,16 @@ func (b *azureAuthBackend) pathRoleCreateUpdate(ctx context.Context, req *logica
|
|||
role.BoundLocations = boundLocations.([]string)
|
||||
}
|
||||
|
||||
if boundScaleSets, ok := data.GetOk("bound_scale_sets"); ok {
|
||||
role.BoundScaleSets = boundScaleSets.([]string)
|
||||
}
|
||||
|
||||
if len(role.BoundServicePrincipalIDs) == 0 &&
|
||||
len(role.BoundGroupIDs) == 0 &&
|
||||
len(role.BoundSubscriptionsIDs) == 0 &&
|
||||
len(role.BoundResourceGroups) == 0 &&
|
||||
len(role.BoundLocations) == 0 {
|
||||
len(role.BoundLocations) == 0 &&
|
||||
len(role.BoundScaleSets) == 0 {
|
||||
return logical.ErrorResponse("must have at least one bound constraint when creating/updating a role"), nil
|
||||
}
|
||||
|
||||
|
|
|
|||
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
|
|
@ -1297,10 +1297,10 @@
|
|||
"revisionTime": "2018-05-30T15:59:58Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "SQ1DvDihitOt2BxCOXn9mrGXnSA=",
|
||||
"checksumSHA1": "bgitTutpYaZwaGQ5VTZjSbPHlmc=",
|
||||
"path": "github.com/hashicorp/vault-plugin-auth-azure",
|
||||
"revision": "5bbc3c8a4d777d9655b6009ace708f725d9679f7",
|
||||
"revisionTime": "2018-06-26T21:25:21Z"
|
||||
"revision": "075d5da053e049e818fdea6ab4225e7d43020a6a",
|
||||
"revisionTime": "2018-07-23T12:29:58Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "LI3ZsYvX/mU/o5EL3gE0qwKcSPs=",
|
||||
|
|
|
|||
|
|
@ -135,6 +135,8 @@ entities attempting to login.
|
|||
is restricted to.
|
||||
- `bound_resource_group_names` `(array: [])` - The list of resource groups that
|
||||
login is restricted to.
|
||||
- `bound_scale_sets` `(array: [])` - The list of scale set names that the
|
||||
login is restricted to.
|
||||
|
||||
### Sample Payload
|
||||
|
||||
|
|
@ -283,6 +285,9 @@ entity and then authorizes the entity for the given role.
|
|||
metadata.
|
||||
- `vm_name` `(string: "")` - The virtual machine name for the machine that
|
||||
generated the MSI token. This information can be obtained through instance
|
||||
metadata. If vmss_name is provided, this value is ignored.
|
||||
- `vmss_name` `(string: "")` - The virtual machine scale set name for the machine
|
||||
that generated the MSI token. This information can be obtained through instance
|
||||
metadata.
|
||||
|
||||
### Sample Payload
|
||||
|
|
|
|||
Loading…
Reference in a new issue