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

agent/azure: adds ability to use specific user-assigned managed identities for auto auth #14214

Merged
merged 6 commits into from
Feb 23, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog/14214.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
agent: Adds ability to configure specific user-assigned managed identities for Azure auto-auth.
```
32 changes: 29 additions & 3 deletions command/agent/auth/azure/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ type azureMethod struct {

role string
resource string
objectID string
austingebauer marked this conversation as resolved.
Show resolved Hide resolved
clientID string
}

func NewAzureAuthMethod(conf *auth.AuthConfig) (auth.AuthMethod, error) {
Expand Down Expand Up @@ -63,11 +65,29 @@ func NewAzureAuthMethod(conf *auth.AuthConfig) (auth.AuthMethod, error) {
return nil, errors.New("could not convert 'resource' config value to string")
}

objectIDRaw, ok := conf.Config["object_id"]
if ok {
a.objectID, ok = objectIDRaw.(string)
if !ok {
return nil, errors.New("could not convert 'object_id' config value to string")
}
}

clientIDRaw, ok := conf.Config["client_id"]
if ok {
a.clientID, ok = clientIDRaw.(string)
if !ok {
return nil, errors.New("could not convert 'client_id' config value to string")
}
}
austingebauer marked this conversation as resolved.
Show resolved Hide resolved

switch {
case a.role == "":
return nil, errors.New("'role' value is empty")
case a.resource == "":
return nil, errors.New("'resource' value is empty")
case a.objectID != "" && a.clientID != "":
return nil, errors.New("only one of 'object_id' or 'client_id' may be provided")
}

return a, nil
Expand All @@ -86,7 +106,7 @@ func (a *azureMethod) Authenticate(ctx context.Context, client *api.Client) (ret
}
}

body, err := getMetadataInfo(ctx, instanceEndpoint, "")
body, err := getMetadataInfo(ctx, instanceEndpoint, "", "", "")
if err != nil {
retErr = err
return
Expand All @@ -103,7 +123,7 @@ func (a *azureMethod) Authenticate(ctx context.Context, client *api.Client) (ret
AccessToken string `json:"access_token"`
}

body, err = getMetadataInfo(ctx, identityEndpoint, a.resource)
body, err = getMetadataInfo(ctx, identityEndpoint, a.resource, a.objectID, a.clientID)
if err != nil {
retErr = err
return
Expand Down Expand Up @@ -138,7 +158,7 @@ func (a *azureMethod) CredSuccess() {
func (a *azureMethod) Shutdown() {
}

func getMetadataInfo(ctx context.Context, endpoint, resource string) ([]byte, error) {
func getMetadataInfo(ctx context.Context, endpoint, resource, objectID, clientID string) ([]byte, error) {
req, err := http.NewRequest("GET", endpoint, nil)
if err != nil {
return nil, err
Expand All @@ -149,6 +169,12 @@ func getMetadataInfo(ctx context.Context, endpoint, resource string) ([]byte, er
if resource != "" {
q.Add("resource", resource)
}
if objectID != "" {
q.Add("object_id", objectID)
}
if clientID != "" {
q.Add("client_id", clientID)
}
req.URL.RawQuery = q.Encode()
req.Header.Set("Metadata", "true")
req.Header.Set("User-Agent", useragent.String())
Expand Down
8 changes: 8 additions & 0 deletions website/content/docs/agent/autoauth/methods/azure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,11 @@ on the value of the `resource` parameter.
- `role` `(string: required)` - The role to authenticate against on Vault

- `resource` `(string: required)` - The resource name to use when getting instance information

- `object_id` `(string: optional)` - The object ID of the user-assigned managed identity to use
when acquiring an [access token](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http).
This parameter is interchangeable with `client_id`. Only one of `object_id` or `client_id` may be provided.

- `client_id` `(string: optional)` - The client ID of the user-assigned managed identity to use
when acquiring an [access token](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http).
This parameter is interchangeable with `object_id`. Only one of `object_id` or `client_id` may be provided.
austingebauer marked this conversation as resolved.
Show resolved Hide resolved