Skip to content

Commit

Permalink
Update managed identity documentation some (#3071)
Browse files Browse the repository at this point in the history
- Clarify that Workload Identity is recommended for production.
- Mention Workload Identity in the getting started section.

This fixes #1326.
  • Loading branch information
matthchr authored Jun 13, 2023
1 parent ac0e5a3 commit 56f0013
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 105 deletions.
6 changes: 3 additions & 3 deletions docs/hugo/content/guide/authentication/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ There are two key topics surrounding authentication in Azure Service Operator: T

Azure Service Operator supports four different styles of authentication today.

1. [Service Principal using a Client Secret]( {{< relref "credential-format#service-principal-using-a-client-secret" >}} )
2. [Service Principal using a Client Certificate]( {{< relref "credential-format#service-principal-using-a-client-certificate" >}} )
3. [Azure-Workload-Identity authentication]( {{< relref "credential-format#azure-workload-identity" >}} ) (OIDC + Managed Identity or Service Principal)
1. [Recommended for production] [Azure-Workload-Identity authentication]( {{< relref "credential-format#azure-workload-identity" >}} ) (OIDC + Managed Identity or Service Principal)
2. [Service Principal using a Client Secret]( {{< relref "credential-format#service-principal-using-a-client-secret" >}} )
3. [Service Principal using a Client Certificate]( {{< relref "credential-format#service-principal-using-a-client-certificate" >}} )
4. [Deprecated] [aad-pod-identity authentication (Managed Identity)]( {{< relref "credential-format#deprecated-managed-identity-aad-pod-identity" >}} )

## Credential scope
Expand Down
209 changes: 108 additions & 101 deletions docs/hugo/content/guide/authentication/credential-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,83 @@ Azure Service Operator supports four different styles of authentication today.
Each section below dives into one of these authentication options, including examples for how to set it up and
use it at the different [credential scopes]( {{< relref "credential-scope" >}} ).

## Service Principal using a Client Secret
## Azure Workload Identity

### Prerequisites
1. An existing Azure Service Principal.
See [Azure Workload Identity](https://github.com/Azure/azure-workload-identity) for details about the workload identity project.

To use Service Principal authentication with **client secret**, create a secret with the `AZURE_CLIENT_ID` and `AZURE_CLIENT_SECRET` keys set.
**Workload identity (with Managed Identity) is the recommended authentication mode for production use-cases**.

For more information about Service Principals, see [creating an Azure Service Principal using the Azure CLI](https://docs.microsoft.com/cli/azure/create-an-azure-service-principal-azure-cli#password-based-authentication).
The `AZURE_CLIENT_ID` is sometimes also called the App ID. The `AZURE_CLIENT_SECRET` is the "password" returned by the command in the previously linked documentation.
### Prerequisites
1. An existing Azure Service Principal or Managed Identity. The setup is the same regardless of which you choose.
2. The [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli).
3. An OIDC endpoint associated with your cluster. See [how to enable OIDC on AKS](https://learn.microsoft.com/en-us/azure/aks/use-oidc-issuer).

Use the following Bash commands to set the environment variables containing the service principal secret (customize with your values):
Use the following Bash commands to set the environment variables containing the workload identity secret (customize with your values):
```bash
export AZURE_CLIENT_ID="00000000-0000-0000-0000-00000000000" # The client ID (sometimes called App Id) of the Service Principal.
export AZURE_CLIENT_SECRET="00000000-0000-0000-0000-00000000000" # The client secret of the Service Principal.
export AZURE_CLIENT_ID="00000000-0000-0000-0000-00000000000" # The client ID (sometimes called App Id) of the Service Principal, or the Client ID of the Managed Identity with which you are using Workload Identity.
export AZURE_SUBSCRIPTION_ID="00000000-0000-0000-0000-00000000000" # The Azure Subscription ID the identity is in.
export AZURE_TENANT_ID="00000000-0000-0000-0000-00000000000" # The Azure AAD Tenant the identity/subscription is associated with.
export SERVICE_ACCOUNT_ISSUER="https://oidc.prod-aks.azure.com/00000000-0000-0000-0000-00000000000/" # The OIDC endpoint for your cluster in this example AKS
```

### Configure trust

Establish trust between your OIDC issuer URL and the backing Service Principal or Managed Identity. See [how it works](https://docs.microsoft.com/en-us/azure/active-directory/develop/workload-identity-federation#how-it-works) for details.

{{< tabpane text=true left=true >}}
{{% tab header="**Kind**:" disabled=true /%}}
{{% tab header="Managed Identity" %}}

Set the following additional environment variables:
```bash
export MI_RESOURCE_GROUP="my-rg" # The resource group containing the managed identity that will be used by ASO
export MI_NAME="my-mi" # The name of the managed identity that will be used by ASO
export APPLICATION_OBJECT_ID=$(az resource show --id /subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${MI_RESOURCE_GROUP}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${MI_NAME} --query "properties.principalId" -o tsv | tr -d '[:space:]')`
```

Create the Federated Identity Credential registering your service account with AAD:
```bash
cat <<EOF > body.json
{
"name": "aso-federated-credential",
"type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials",
"properties": {
"issuer":"${SERVICE_ACCOUNT_ISSUER}",
"subject":"system:serviceaccount:azureserviceoperator-system:azureserviceoperator-default",
"audiences": [
"api://AzureADTokenExchange"
]
}
}
EOF
az rest --method put --url /subscriptions/${AZURE_SUBSCRIPTION_ID}/resourcegroups/${MI_RESOURCE_GROUP}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${MI_NAME}/federatedIdentityCredentials/aso-federated-credential?api-version=2022-01-31-preview --body @body.json
```

{{% /tab %}}
{{% tab header="Service Principal" %}}

```bash
export APPLICATION_OBJECT_ID="$(az ad app show --id ${AZURE_CLIENT_ID} --query id -otsv)"
cat <<EOF > params.json
{
"name": "aso-federated-credential",
"issuer": "${SERVICE_ACCOUNT_ISSUER}",
"subject": "system:serviceaccount:azureserviceoperator-system:azureserviceoperator-default",
"description": "Kubernetes service account federated credential",
"audiences": [
"api://AzureADTokenExchange"
]
}
EOF
az ad app federated-credential create --id ${APPLICATION_OBJECT_ID} --parameters @params.json
```

{{% /tab %}}
{{< /tabpane >}}

### Create the secret

{{< tabpane text=true left=true >}}
Expand All @@ -40,7 +99,7 @@ helm upgrade --install --devel aso2 aso2/azure-service-operator \
--set azureSubscriptionID=$AZURE_SUBSCRIPTION_ID \
--set azureTenantID=$AZURE_TENANT_ID \
--set azureClientID=$AZURE_CLIENT_ID \
--set azureClientSecret=$AZURE_CLIENT_SECRET \
--set useWorkloadIdentityAuth=true \
--set crdPattern='resources.azure.com/*;containerservice.azure.com/*;keyvault.azure.com/*;managedidentity.azure.com/*;eventhub.azure.com/*'
```

Expand All @@ -59,7 +118,7 @@ stringData:
AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID"
AZURE_TENANT_ID: "$AZURE_TENANT_ID"
AZURE_CLIENT_ID: "$AZURE_CLIENT_ID"
AZURE_CLIENT_SECRET: "$AZURE_CLIENT_SECRET"
USE_WORKLOAD_IDENTITY_AUTH: "true"
EOF
```

Expand All @@ -82,10 +141,12 @@ stringData:
AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID"
AZURE_TENANT_ID: "$AZURE_TENANT_ID"
AZURE_CLIENT_ID: "$AZURE_CLIENT_ID"
AZURE_CLIENT_SECRET: "$AZURE_CLIENT_SECRET"
EOF
```

**Note:** Each credential (both namespaced and per-resource) you create must have a trust relationship between your OIDC
issuer URL and the backing Service Principal or Managed Identity. See [how to configure trust](#configure-trust) for more details.

{{% /tab %}}
{{% tab header="Resource" %}}

Expand All @@ -101,7 +162,6 @@ stringData:
AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID"
AZURE_TENANT_ID: "$AZURE_TENANT_ID"
AZURE_CLIENT_ID: "$AZURE_CLIENT_ID"
AZURE_CLIENT_SECRET: "$AZURE_CLIENT_SECRET"
EOF
```
Expand All @@ -121,28 +181,28 @@ spec:
EOF
```
**Note:** Each credential (both namespaced and per-resource) you create must have a trust relationship between your OIDC
issuer URL and the backing Service Principal or Managed Identity. See [how to configure trust](#configure-trust) for more details.
{{% /tab %}}
{{< /tabpane >}}

## Service Principal using a Client Certificate
## Service Principal using a Client Secret
### Prerequisites
1. An existing Azure Service Principal.
2. X.509 certificate in ASCII format such as PEM, CER, or DER.
To use Service Principal authentication via client certificate, create a secret with the `AZURE_CLIENT_ID`, `AZURE_CLIENT_CERTIFICATE` and `AZURE_CLIENT_CERTIFICATE_PASSWORD`(optional) keys set.
To use Service Principal authentication with **client secret**, create a secret with the `AZURE_CLIENT_ID` and `AZURE_CLIENT_SECRET` keys set.
For more information about creating Service Principals with certificate, see [creating an Azure Service Principal using the Azure CLI](https://learn.microsoft.com/cli/azure/create-an-azure-service-principal-azure-cli#certificate-based-authentication).
The `AZURE_CLIENT_ID` is sometimes also called the App ID. The `AZURE_CLIENT_CERTIFICATE` is the _certificate_ returned by the command in the previously linked documentation.
For more information about Service Principals, see [creating an Azure Service Principal using the Azure CLI](https://docs.microsoft.com/cli/azure/create-an-azure-service-principal-azure-cli#password-based-authentication).
The `AZURE_CLIENT_ID` is sometimes also called the App ID. The `AZURE_CLIENT_SECRET` is the "password" returned by the command in the previously linked documentation.
Use the following Bash commands to set the environment variables containing the service principal certificate secret (customize with your values):
Use the following Bash commands to set the environment variables containing the service principal secret (customize with your values):
```bash
export AZURE_CLIENT_ID="00000000-0000-0000-0000-00000000000" # The client ID (sometimes called App Id) of the Service Principal.
export AZURE_SUBSCRIPTION_ID="00000000-0000-0000-0000-00000000000" # The Azure Subscription ID the identity is in.
export AZURE_TENANT_ID="00000000-0000-0000-0000-00000000000" # The Azure AAD Tenant the identity/subscription is associated with.
export AZURE_CLIENT_CERTIFICATE=`cat path/to/certFile.pem` # The client certificate of the Service Principal.
export AZURE_CLIENT_CERTIFICATE_PASSWORD="myPrivateKeyValue" # The private key for the above certificate (optional)
export AZURE_CLIENT_ID="00000000-0000-0000-0000-00000000000" # The client ID (sometimes called App Id) of the Service Principal.
export AZURE_CLIENT_SECRET="00000000-0000-0000-0000-00000000000" # The client secret of the Service Principal.
export AZURE_SUBSCRIPTION_ID="00000000-0000-0000-0000-00000000000" # The Azure Subscription ID the identity is in.
export AZURE_TENANT_ID="00000000-0000-0000-0000-00000000000" # The Azure AAD Tenant the identity/subscription is associated with.
```
### Create the secret
Expand All @@ -159,7 +219,7 @@ helm upgrade --install --devel aso2 aso2/azure-service-operator \
--set azureSubscriptionID=$AZURE_SUBSCRIPTION_ID \
--set azureTenantID=$AZURE_TENANT_ID \
--set azureClientID=$AZURE_CLIENT_ID \
--set azureClientCertificatePassword=$AZURE_CLIENT_CERTIFICATE_PASSWORD \
--set azureClientSecret=$AZURE_CLIENT_SECRET \
--set crdPattern='resources.azure.com/*;containerservice.azure.com/*;keyvault.azure.com/*;managedidentity.azure.com/*;eventhub.azure.com/*'
```
Expand All @@ -178,8 +238,7 @@ stringData:
AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID"
AZURE_TENANT_ID: "$AZURE_TENANT_ID"
AZURE_CLIENT_ID: "$AZURE_CLIENT_ID"
AZURE_CLIENT_CERTIFICATE: "$AZURE_CLIENT_CERTIFICATE"
AZURE_CLIENT_CERTIFICATE_PASSWORD: "$AZURE_CLIENT_CERTIFICATE_PASSWORD"
AZURE_CLIENT_SECRET: "$AZURE_CLIENT_SECRET"
EOF
```
Expand All @@ -202,8 +261,7 @@ stringData:
AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID"
AZURE_TENANT_ID: "$AZURE_TENANT_ID"
AZURE_CLIENT_ID: "$AZURE_CLIENT_ID"
AZURE_CLIENT_CERTIFICATE: "$AZURE_CLIENT_CERTIFICATE"
AZURE_CLIENT_CERTIFICATE_PASSWORD: "$AZURE_CLIENT_CERTIFICATE_PASSWORD"
AZURE_CLIENT_SECRET: "$AZURE_CLIENT_SECRET"
EOF
```
Expand All @@ -222,8 +280,7 @@ stringData:
AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID"
AZURE_TENANT_ID: "$AZURE_TENANT_ID"
AZURE_CLIENT_ID: "$AZURE_CLIENT_ID"
AZURE_CLIENT_CERTIFICATE: "$AZURE_CLIENT_CERTIFICATE"
AZURE_CLIENT_CERTIFICATE_PASSWORD: "$AZURE_CLIENT_CERTIFICATE_PASSWORD"
AZURE_CLIENT_SECRET: "$AZURE_CLIENT_SECRET"
EOF
```

Expand All @@ -246,74 +303,25 @@ EOF
{{% /tab %}}
{{< /tabpane >}}

## Azure Workload Identity

See [Azure Workload Identity](https://github.com/Azure/azure-workload-identity) for details about the workload identity project.
## Service Principal using a Client Certificate

### Prerequisites
1. An existing Azure Service Principal or Managed Identity. The setup is the same regardless of which you choose.
2. The [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli).

Use the following Bash commands to set the environment variables containing the workload identity secret (customize with your values):
```bash
export AZURE_CLIENT_ID="00000000-0000-0000-0000-00000000000" # The client ID (sometimes called App Id) of the Service Principal, or the Client ID of the Managed Identity with which you are using Workload Identity.
export AZURE_SUBSCRIPTION_ID="00000000-0000-0000-0000-00000000000" # The Azure Subscription ID the identity is in.
export AZURE_TENANT_ID="00000000-0000-0000-0000-00000000000" # The Azure AAD Tenant the identity/subscription is associated with.
export SERVICE_ACCOUNT_ISSUER="https://oidc.prod-aks.azure.com/00000000-0000-0000-0000-00000000000/" # The OIDC endpoint for your cluster in this example AKS
```

### Get the Application Object ID of the identity

For Managed Identity: `export APPLICATION_OBJECT_ID=$(az resource show --id /subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/{my resource group name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{my managed identity name} --query "properties.principalId" -o tsv | tr -d '[:space:]')`

### Configure trust

Establish trust between your OIDC issuer URL and the backing Service Principal or Managed Identity. See [how it works](https://docs.microsoft.com/en-us/azure/active-directory/develop/workload-identity-federation#how-it-works) for details.

#### Service Principal

```bash
export APPLICATION_OBJECT_ID="$(az ad app show --id ${AZURE_CLIENT_ID} --query id -otsv)"

cat <<EOF > params.json
{
"name": "aso-federated-credential",
"issuer": "${SERVICE_ACCOUNT_ISSUER}",
"subject": "system:serviceaccount:azureserviceoperator-system:azureserviceoperator-default",
"description": "Kubernetes service account federated credential",
"audiences": [
"api://AzureADTokenExchange"
]
}
EOF

az ad app federated-credential create --id ${APPLICATION_OBJECT_ID} --parameters @params.json
```
1. An existing Azure Service Principal.
2. X.509 certificate in ASCII format such as PEM, CER, or DER.

#### Managed Identity
To use Service Principal authentication via client certificate, create a secret with the `AZURE_CLIENT_ID`, `AZURE_CLIENT_CERTIFICATE` and `AZURE_CLIENT_CERTIFICATE_PASSWORD`(optional) keys set.

Set the following additional environment variables:
```bash
export MI_RESOURCE_GROUP="my-rg" # The resource group containing the managed identity that will be used by ASO
export MI_NAME="my-mi" # The name of the managed identity that will be used by ASO
```
For more information about creating Service Principals with certificate, see [creating an Azure Service Principal using the Azure CLI](https://learn.microsoft.com/cli/azure/create-an-azure-service-principal-azure-cli#certificate-based-authentication).
The `AZURE_CLIENT_ID` is sometimes also called the App ID. The `AZURE_CLIENT_CERTIFICATE` is the _certificate_ returned by the command in the previously linked documentation.

Use the following Bash commands to set the environment variables containing the service principal certificate secret (customize with your values):
```bash
cat <<EOF > body.json
{
"name": "aso-federated-credential",
"type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials",
"properties": {
"issuer":"${SERVICE_ACCOUNT_ISSUER}",
"subject":"system:serviceaccount:azureserviceoperator-system:azureserviceoperator-default",
"audiences": [
"api://AzureADTokenExchange"
]
}
}
EOF

az rest --method put --url /subscriptions/${AZURE_SUBSCRIPTION_ID}/resourcegroups/${MI_RESOURCE_GROUP}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${MI_NAME}/federatedIdentityCredentials/aso-federated-credential?api-version=2022-01-31-preview --body @body.json
export AZURE_CLIENT_ID="00000000-0000-0000-0000-00000000000" # The client ID (sometimes called App Id) of the Service Principal.
export AZURE_SUBSCRIPTION_ID="00000000-0000-0000-0000-00000000000" # The Azure Subscription ID the identity is in.
export AZURE_TENANT_ID="00000000-0000-0000-0000-00000000000" # The Azure AAD Tenant the identity/subscription is associated with.
export AZURE_CLIENT_CERTIFICATE=`cat path/to/certFile.pem` # The client certificate of the Service Principal.
export AZURE_CLIENT_CERTIFICATE_PASSWORD="myPrivateKeyValue" # The private key for the above certificate (optional)
```

### Create the secret
Expand All @@ -330,7 +338,7 @@ helm upgrade --install --devel aso2 aso2/azure-service-operator \
--set azureSubscriptionID=$AZURE_SUBSCRIPTION_ID \
--set azureTenantID=$AZURE_TENANT_ID \
--set azureClientID=$AZURE_CLIENT_ID \
--set useWorkloadIdentityAuth=true \
--set azureClientCertificatePassword=$AZURE_CLIENT_CERTIFICATE_PASSWORD \
--set crdPattern='resources.azure.com/*;containerservice.azure.com/*;keyvault.azure.com/*;managedidentity.azure.com/*;eventhub.azure.com/*'
```

Expand All @@ -349,7 +357,8 @@ stringData:
AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID"
AZURE_TENANT_ID: "$AZURE_TENANT_ID"
AZURE_CLIENT_ID: "$AZURE_CLIENT_ID"
USE_WORKLOAD_IDENTITY_AUTH: "true"
AZURE_CLIENT_CERTIFICATE: "$AZURE_CLIENT_CERTIFICATE"
AZURE_CLIENT_CERTIFICATE_PASSWORD: "$AZURE_CLIENT_CERTIFICATE_PASSWORD"
EOF
```

Expand All @@ -372,12 +381,11 @@ stringData:
AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID"
AZURE_TENANT_ID: "$AZURE_TENANT_ID"
AZURE_CLIENT_ID: "$AZURE_CLIENT_ID"
AZURE_CLIENT_CERTIFICATE: "$AZURE_CLIENT_CERTIFICATE"
AZURE_CLIENT_CERTIFICATE_PASSWORD: "$AZURE_CLIENT_CERTIFICATE_PASSWORD"
EOF
```

**Note:** Each credential (both namespaced and per-resource) you create must have a trust relationship between your OIDC
issuer URL and the backing Service Principal or Managed Identity. See [how to configure trust](#configure-trust) for more details.

{{% /tab %}}
{{% tab header="Resource" %}}

Expand All @@ -393,6 +401,8 @@ stringData:
AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID"
AZURE_TENANT_ID: "$AZURE_TENANT_ID"
AZURE_CLIENT_ID: "$AZURE_CLIENT_ID"
AZURE_CLIENT_CERTIFICATE: "$AZURE_CLIENT_CERTIFICATE"
AZURE_CLIENT_CERTIFICATE_PASSWORD: "$AZURE_CLIENT_CERTIFICATE_PASSWORD"
EOF
```
Expand All @@ -412,9 +422,6 @@ spec:
EOF
```
**Note:** Each credential (both namespaced and per-resource) you create must have a trust relationship between your OIDC
issuer URL and the backing Service Principal or Managed Identity. See [how to configure trust](#configure-trust) for more details.

{{% /tab %}}
{{< /tabpane >}}
Expand Down
Loading

0 comments on commit 56f0013

Please sign in to comment.