Azure Authenticator
This topic describes the Conjur Azure Authenticator.
Overview
The Conjur Azure Authenticator is a highly secure method for authenticating Azure workloads to Conjur using their underlying Microsoft Azure attributes. A Conjur identity can be established at varying granularity, allowing for a collection of resources to be identified to Conjur as one, or for individual workloads to be uniquely identified. The method is based on Microsoft Azure AD Authentication, presenting developers with a familiar pattern.
The Azure Authenticator can be used instead of API key based authentication, leading to a higher security posture with no need to store a ‘secret-zero’.
The following diagram depicts the layered identification model:
This model offers the following options:
-
You can associate a set of workloads with one Conjur identity, defined by the subscription and resource group properties only
-
You can associate each individual Azure workload with a unique Conjur identity by including its user-assigned or system-assigned Azure managed identity in its definition.
User-assigned managed identities are useful for pre-populating a Conjur host policy before the Azure resource is created. They can also be used to share the same Conjur identity among specific Azure resources within the resource group.
System-assigned managed identities are created on the fly, so they need to be loaded into the Conjur host policy at run time after the resource is created as part of the pipeline automation.
This layered approach allows you to authenticate workloads whether or not you are working with Azure managed identities. |
Supported Azure services
-
Azure Virtual Machines
-
Azure App Services
-
Azure Functions
-
Azure Container Instances
How it works
This section describes how an application running on an Azure resource authenticates with Conjur to retrieve secrets.
-
An application requests its Azure AD token from the Azure Instance Metadata Service (IMDS).
-
The IMDS responds with a signed JWT token.
-
The application sends an authentication request to Conjur using the Authenticate using Azure Authenticator REST API.
-
Conjur attempts to authenticate and authorize the request. If successful, Conjur sends a short-lived access token back to the application.
-
The application can retrieve secrets stored in Conjur.
Configure the Azure Authenticator
To communicate with and retrieve secrets from Conjur, the application running in Azure needs to authenticate to Conjur and receive a Conjur access token.
This section describes how to configure the Azure Authenticator, and how to define applications to use the Azure Authenticator to authenticate to Conjur.
-
Before you begin
Before you begin, have the following information ready:
This information can be found in the Azure portal. For more details, see the Microsoft Azure documentation.
What you need
Description
The URI of your Azure Provider: https://sts.windows.net/<tenant_id>/.
For example: https://sts.windows.net/00000000-0000-0000-0000-000000000000/.
Tip: You can fetch the provider_uri from the Azure portal or, if your resource is an Azure VM, by running the following on the Azure VM:
curl -s -H Metadata:true "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/" | jq -r .access_token | awk -F "." '{print $2}' | base64 -d | jq -r .iss
Subscription ID
The ID of the subscription associated with your Microsoft Azure account.
Resource group
(case-sensitive)
The logical collection that your Azure resource belongs to
(case-sensitive)
(Optional) One of the Azure instance's managed identities:
-
User-assigned managed identity: The readable name given to the application on Azure.
-
System-assigned managed identity: Your application's Object ID .
-
-
Define Azure Authenticator policy
In this step you define the Azure Authenticator in policy, and detail a group of Conjur hosts (applications) that have permission to use the Azure Authenticator to authenticate with Conjur.
All Azure Authenticator policy IDs must have the authentication type prefix,
conjur/authn-azure
.A Conjur Server can have multiple webservices all of the same
conjur/authn-azure
authenticator type. To differentiate between each webservice, you append aservice ID
to the authenticator type.In addition, in the policy a status API is defined for this authenticator. The Authenticator Status (
status
) webservice verifies the status of the authenticator. It identifies whether or not the authenticator configuration was successful. We will usestatus
in the last step of this configuration. Make sure to grant permissions to the user groups that should be able to check authenticator status by adding them to the operators group.For more information about service IDs for Authenticators, see Authenticator service IDs.
-
Copy the following policy and, in the policy ID, replace <service-id> with an identity for the Azure Authenticator:
- !policy id: conjur/authn-azure/<service-id> body: - !webservice - !variable id: provider-uri - !group id: apps annotations: description: Group of hosts that can authenticate using the authn-azure/<service-id> authenticator - !permit role: !group apps privilege: [ read, authenticate ] resource: !webservice - !webservice id: status annotations: description: Status service to check that the authenticator is configured correctly - !group id: operators annotations: description: Group of users who can check the status of the authenticator - !permit role: !group operators privilege: [ read ] resource: !webservice status
For example, if the webservice ID is AzureWS1:
- !policy id: conjur/authn-azure/AzureWS1 body: - !webservice - !variable id: provider-uri - !group id: apps annotations: description: Group of hosts that can authenticate using the authn-azure/AzureWS1 authenticator - !permit role: !group apps privilege: [ read, authenticate ] resource: !webservice - !webservice id: status annotations: description: Status service to check that the authenticator is configured correctly - !group id: operators annotations: description: Group of users who can check the status of the authenticator - !permit role: !group operators privilege: [ read ] resource: !webservice status
-
Save the policy as a YAML file using the following file naming convention, authn-azure-<service-id>.yml, and load it into root:
conjur policy load -b root -f authn-azure-<service-id>.yml
For example:
conjur policy load -b root -f authn-azure-AzureWS1.yml
-
Populate the
provider_uri
variable with the provider_uri from Azure:conjur variable set -i conjur/authn-azure/<service_id>/provider-uri -v <provider_uri>
For example:
$
conjur variable set -i conjur/authn-azure/AzureWS1/provider-uri -v https://sts.windows.net/00000000-0000-0000-0000-000000000000/
-
-
Define the Azure resource as a Conjur host in policy
In this step, you give the Azure instance an identity in Conjur, and define the application identity for each Azure instance in Conjur in the host annotations.
Use the following guidelines when defining the host annotations to represent the Azure resource:
- Each host must include annotations for the subscription ID and for the resource group (case-sensitive).
-
Optional: For an extra level of security, provide either one of the Azure instance's system-assigned or user-assigned managed identities (case-sensitive):
-
If the Azure resource has a user-assigned managed identity, add this identity to the host annotations. The host can be used for several Azure resources, with or without this identity in its annotations.
- If you prefer to use the Azure instance's system-assigned managed identity, add its Object ID to the host annotations.
-
To define the Azure resource as a host:
-
Copy the following policy:
- !policy id: <policy-id> body: - !group - &hosts - !host id: <host-id> annotations: authn-azure/subscription-id: <subscription-id> authn-azure/resource-group: <resource-group> # authn-azure/user-assigned-identity: <user-assigned managed identity> # authn-azure/system-assigned-identity: <Object ID> - !grant role: !group members: *hosts - !grant role: !group /conjur/authn-azure/<service-id>/apps member: !group <policy-id>
-
To use a managed identity, uncomment the relevant host annotation in the policy.
-
If you are loading the policy into a path other than root, make sure to include the slash (/) preceding the path in
role: !group /conjur/authn-azure/<SERVICE_ID>/apps
.The slash ensures that the path is rooted.
If you are loading the policy into root, make sure to EXCLUDE the slash (/) preceding the path, as follows:
role: !group conjur/authn-azure/<SERVICE_ID>/apps
.
The following example defines an Azure VM as a host using its system-assigned managed identity:
- !policy id: azure-apps body: - !group - &hosts - !host id: azureVM annotations: authn-azure/subscription-id: subscr1pt10n-1dmy-subsc-r1pt10n1d authn-azure/resource-group: myResourceGroup # authn-azure/user-assigned-identity: <user-assigned managed identity> authn-azure/system-assigned-identity: 0000aaaa-00aa-00aa-00aa-00000aaaaa - !grant role: !group members: *hosts - !grant role: !group /conjur/authn-azure/AzureWS1/apps member: !group azure-apps
-
-
Save the policy as a YAML file, using the following naming convention:
authn-azure-<service-id>-hosts.yml, and load the policy file into any policy level:
conjur policy load -b <policy-path> -f authn-azure-<service-id>-hosts.yml
For example:
$
conjur policy load -b my/policy/path -f authn-azure-AzureWS1-hosts.yml
-
Define secrets and access for Azure instances
-
Define Conjur secrets and a group that has permissions on the secrets.
In the following example, all members of the
consumers
group are granted permissions on thetest-variable
secret.- !policy id: secrets body: - !group consumers - !variable test-variable - !permit role: !group consumers privilege: [ read, execute ] resource: !variable test-variable - !grant role: !group secrets/consumers member: !group azure-apps
-
Save the policy as authn-azure-secrets.yml.
-
Load the policy file into root:
conjur policy load -b root -f authn-azure-secrets.yml
-
Populate the secret with a value. For example:
$ conjur variable set -i secrets/test-variable -v mySecret
-
-
Enable the Azure Authenticator
In this step, you add the Azure Authenticator to the list of allowed authenticators in Conjur.
Set the CONJUR_AUTHENTICATORS variable as an environment variable: CONJUR_AUTHENTICATORS=<authenticator-name>
The value for this variable must be identical to the name given to the authenticator policy ID above, excluding the conjur/ prefix.
For example:
CONJUR_AUTHENTICATORS=authn-azure/AzureWS1
Retrieve an Azure AD token
To authenticate with Conjur, you need an Azure AD token.
The following procedure is an example of how to retrieve an Azure AD token from an Azure VM using the IMDS REST API:
-
Make sure that you can access managed identities on the VM.
-
Log in to the Azure VM.
-
Run the following command, where <api_version> is the IMDS version. Use 2018-02-01 or greater:
Token type Command User-assigned managed identity
The following command requires the <client_ID> which can be found in the Azure portal.
curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=<api_version>&client_id=<client_id>&resource=https%3A%2F%2Fmanagement.azure.com%2F' -H Metadata:true -s | jq -r '.access_token'
System-assigned managed identity
curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=<api_version>&resource=https%3A%2F%2Fmanagement.azure.com%2F' -H Metadata:true -s | jq -r '.access_token'
When using a system-assigned managed identity, make sure that system-assigned managed identity is enabled in Azure. For details, see the Microsoft Azure documentation.
Send an Azure authentication request
Once the Azure Authenticator is configured, you can send an authentication request from the Azure instance to Conjur using the Azure Authenticator REST API.
Use the following URI to send an authentication request to Conjur:
|
Parameter |
Description |
---|---|
service-id |
The ID of your Azure Authenticator webservice , for example AzureWS1 |
account |
The organization account name |
host-id |
The identity of the application running on the Azure VM. This value should be the full hostname and should include URL encoding for the forward slash (/), for example, host%2Fazure-apps%2FazureVM. |
Example of request:
|
For more details about sending authentication requests, see the Authenticate using Azure Authenticator REST API.
Troubleshooting the Azure Authenticator
This section lists issues that may arise and recommended solutions:
Check the authenticator status using the Authenticator Status API. For details, see Authenticator Status Webservice.
Make sure that system-assigned managed identity is enabled in Azure. For details, see the Microsoft Azure documentation.