From c66e92354aa7a5330dae0a9e46be117ca9650207 Mon Sep 17 00:00:00 2001 From: cathylin-wang Date: Thu, 18 Jun 2026 15:58:53 -0400 Subject: [PATCH 1/4] feat: write docs for azure wif connection --- cloud-accounts/connecting-a-cloud-account.mdx | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) diff --git a/cloud-accounts/connecting-a-cloud-account.mdx b/cloud-accounts/connecting-a-cloud-account.mdx index d71e982..675d05a 100644 --- a/cloud-accounts/connecting-a-cloud-account.mdx +++ b/cloud-accounts/connecting-a-cloud-account.mdx @@ -136,6 +136,191 @@ Before Porter can create a cluster, you need to grant it access to your cloud ac + Porter connects to Azure using a service principal authenticated via [workload identity federation](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation) to manage your infrastructure. + + ## Create the Service Principal + + You can create the service principal using our automated script (recommended) or manually. Both flows need the **OIDC subject** and **OIDC issuer** that Porter shows in the dashboard during the Azure cloud account connection — copy these before starting. + + + + If you have the Azure CLI installed and authenticated (`az login`), run our setup script: + + ```bash + # Download the setup script + curl -O https://raw.githubusercontent.com/porter-dev/docs/main/scripts/setup-azure-porter-wif.sh + + # Make it executable + chmod +x setup-azure-porter-wif.sh + + # Run the script with the OIDC subject and issuer from Porter + ./setup-azure-porter-wif.sh \ + --subject \ + --issuer + ``` + + The script: + - Enables all required Azure resource providers + - Creates the custom `porter-aks-restricted` role + - Creates the app registration and service principal with proper permissions + - Adds Microsoft Graph API permissions + - Grants admin consent (if you have permissions) + - Adds the federated identity credential trusting Porter's OIDC issuer + - Displays the credentials needed for Porter + + + If the script fails to grant admin consent automatically, grant it manually in the Azure Portal: **App registrations** > **azure-porter-federated-sp** > **API permissions** > **Grant admin consent for Default Directory**. + + + + + ### Enable Resource Providers + + Before creating the service principal, enable the required resource providers: + + 1. In the Azure portal, search for **Subscriptions** + 2. Select your subscription and click **Resource providers** + 3. Enable the following providers by selecting them and clicking **Register**: + - Microsoft.Capacity + - Microsoft.Compute + - Microsoft.ContainerRegistry + - Microsoft.ContainerService + - Microsoft.ManagedIdentity + - Microsoft.Network + - Microsoft.OperationalInsights + - Microsoft.OperationsManagement + - Microsoft.ResourceGraph + - Microsoft.Resources + - Microsoft.Storage + + Registration may take a few minutes per provider. Confirm all providers are enabled before proceeding. + + ### Create the Custom Role + + Run the following commands in the Azure Cloud Shell (Bash) or your local terminal with the Azure CLI: + + ```bash + # Set your subscription ID + PORTER_AZURE_SUBSCRIPTION_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + + # Create the role + envsubst << EOF | az role definition create --role-definition @- + { + "assignableScopes": ["/subscriptions/${PORTER_AZURE_SUBSCRIPTION_ID}"], + "description": "Grants Porter access to manage resources for an AKS cluster.", + "id": "/subscriptions/${PORTER_AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Authorization/roleDefinitions/porter-aks-restricted", + "isCustom": true, + "name": "porter-aks-restricted", + "permissions": [ + { + "actions": ["*"], + "dataActions": [], + "notActions": [ + "Microsoft.Authorization/elevateAccess/Action", + "Microsoft.Blueprint/blueprintAssignments/write", + "Microsoft.Blueprint/blueprintAssignments/delete", + "Microsoft.Compute/galleries/share/action" + ], + "notDataActions": [] + } + ], + "roleName": "Contributor", + "roleType": "BuiltInRole", + "type": "Microsoft.Authorization/roleDefinitions" + } + EOF + ``` + + ### Create the Service Principal + + ```bash + # Create the app registration and capture its Application (Client) ID + APP_ID=$(az ad app create --display-name "azure-porter-federated-sp" --query appId -o tsv) + + # Create the matching service principal + az ad sp create --id "$APP_ID" + + # Wait for the service principal to propagate before assigning a role to it + sleep 10 + + # Assign the custom role at the subscription scope + az role assignment create \ + --assignee "$APP_ID" \ + --role "porter-aks-restricted" \ + --scope "/subscriptions/${PORTER_AZURE_SUBSCRIPTION_ID}" + ``` + + Save the `APP_ID` — you'll enter it in Porter as the Application (Client) ID. Get your Tenant ID with `az account show --query tenantId -o tsv`. + + ### Add the Federated Identity Credential + + Trust Porter's OIDC issuer to exchange tokens for this app registration. Use the **OIDC subject** and **OIDC issuer** shown in Porter: + + ```bash + # Values copied from the Porter dashboard + PORTER_OIDC_SUBJECT= + PORTER_OIDC_ISSUER= + + # Derive a name from the project ID in the subject + PROJECT_ID="${PORTER_OIDC_SUBJECT##*-}" + + az ad app federated-credential create \ + --id "$APP_ID" \ + --parameters "{ + \"name\": \"porter-project-${PROJECT_ID}\", + \"issuer\": \"${PORTER_OIDC_ISSUER}\", + \"subject\": \"${PORTER_OIDC_SUBJECT}\", + \"audiences\": [\"api://AzureADTokenExchange\"] + }" + ``` + + + Azure can take a few minutes to propagate the federated credential. If Porter rejects the first connection attempt, wait a moment and retry. + + + ### Grant API Permissions + + 1. In the Azure portal, search for **App registrations** + 2. Under **All applications**, select your new service principal + 3. Navigate to **API Permissions** + 4. Click **Add a permission** → **Microsoft Graph** → **Application permissions** + 5. Select these permissions: + - Application.ReadWrite.All + - Directory.ReadWrite.All + - Domain.Read.All + - Group.Create + - Group.ReadWrite.All + - RoleManagement.ReadWrite.Directory + - User.ReadWrite.All + 6. Click **Add permissions** + 7. Click **Grant admin consent for Default Directory** + + + + ## Enter Credentials in Porter + + In Porter, enter the following values from your service principal: + + | Field | Value | + |-------|-------| + | **Subscription ID** | Your Azure subscription ID | + | **Application (Client) ID** | The `appId` from your app registration | + | **Tenant ID** | Your Azure tenant ID (`az account show --query tenantId -o tsv`) | + + No client secret is required — Porter authenticates by exchanging its OIDC token for short-lived Azure credentials. + + ## Revoking Access + + To revoke Porter's access: + + 1. First, delete any clusters through the Porter dashboard + 2. In the Azure portal, search for **App registrations** and delete **azure-porter-federated-sp** + 3. Optionally, delete the custom role definition + + This removes the service principal and prevents Porter from accessing your account. + + + Porter connects to Azure using a service principal with permissions to manage your infrastructure. ## Create the Service Principal From ae27acda59a692b4f56d89fe8e9043fef1d3093d Mon Sep 17 00:00:00 2001 From: cathylin-wang Date: Thu, 18 Jun 2026 16:12:20 -0400 Subject: [PATCH 2/4] just delete old tabs --- cloud-accounts/connecting-a-cloud-account.mdx | 170 +----------------- 1 file changed, 1 insertion(+), 169 deletions(-) diff --git a/cloud-accounts/connecting-a-cloud-account.mdx b/cloud-accounts/connecting-a-cloud-account.mdx index 675d05a..02f767d 100644 --- a/cloud-accounts/connecting-a-cloud-account.mdx +++ b/cloud-accounts/connecting-a-cloud-account.mdx @@ -1,7 +1,7 @@ --- title: "Connecting a cloud account" sidebarTitle: "Connecting a Cloud Account" -description: "Grant Porter access to your AWS, GCP, or Azure account using IAM roles, Workload Identity Federation, or service principals to provision infrastructure" +description: "Grant Porter access to your AWS, GCP, or Azure account using IAM role assumption or Workload Identity Federation to provision infrastructure" --- Before Porter can create a cluster, you need to grant it access to your cloud account. Porter uses secure credential methods that don't require storing static API keys. @@ -319,173 +319,5 @@ Before Porter can create a cluster, you need to grant it access to your cloud ac This removes the service principal and prevents Porter from accessing your account. - - - Porter connects to Azure using a service principal with permissions to manage your infrastructure. - - ## Create the Service Principal - - You can create the service principal using our automated script (recommended) or manually. - - - - If you have the Azure CLI installed and authenticated (`az login`), run our setup script: - - ```bash - # Download the setup script - curl -O https://raw.githubusercontent.com/porter-dev/docs/main/scripts/setup-azure-porter.sh - - # Make it executable - chmod +x setup-azure-porter.sh - - # Run the script (optionally provide subscription ID) - ./setup-azure-porter.sh [your-subscription-id] - ``` - - The script: - - Enables all required Azure resource providers - - Creates the custom `porter-aks-restricted` role - - Creates the service principal with proper permissions - - Adds Microsoft Graph API permissions - - Grants admin consent (if you have permissions) - - Displays the credentials needed for Porter - - - If the script fails to grant admin consent automatically, grant it manually in the Azure Portal: **App registrations** > **azure-porter-restricted-sp** > **API permissions** > **Grant admin consent for Default Directory**. - - - - - ### Enable Resource Providers - - Before creating the service principal, enable the required resource providers: - - 1. In the Azure portal, search for **Subscriptions** - 2. Select your subscription and click **Resource providers** - 3. Enable the following providers by selecting them and clicking **Register**: - - Microsoft.Capacity - - Microsoft.Compute - - Microsoft.ContainerRegistry - - Microsoft.ContainerService - - Microsoft.KeyVault - - Microsoft.ManagedIdentity - - Microsoft.Network - - Microsoft.OperationalInsights - - Microsoft.OperationsManagement - - Microsoft.ResourceGraph - - Microsoft.Resources - - Microsoft.Storage - - Registration may take a few minutes per provider. Confirm all providers are enabled before proceeding. - - ### Create the Custom Role - - Run the following commands in the Azure Cloud Shell (Bash) or your local terminal with the Azure CLI: - - ```bash - # Set your subscription ID - PORTER_AZURE_SUBSCRIPTION_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - - # Create the role - envsubst << EOF | az role definition create --role-definition @- - { - "assignableScopes": ["/subscriptions/${PORTER_AZURE_SUBSCRIPTION_ID}"], - "description": "Grants Porter access to manage resources for an AKS cluster.", - "id": "/subscriptions/${PORTER_AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Authorization/roleDefinitions/porter-aks-restricted", - "isCustom": true, - "name": "porter-aks-restricted", - "permissions": [ - { - "actions": ["*"], - "dataActions": [], - "notActions": [ - "Microsoft.Authorization/elevateAccess/Action", - "Microsoft.Blueprint/blueprintAssignments/write", - "Microsoft.Blueprint/blueprintAssignments/delete", - "Microsoft.Compute/galleries/share/action" - ], - "notDataActions": [] - } - ], - "roleName": "Contributor", - "roleType": "BuiltInRole", - "type": "Microsoft.Authorization/roleDefinitions" - } - EOF - ``` - - ### Create the Service Principal - - ```bash - az ad sp create-for-rbac \ - --name="azure-porter-restricted-sp" \ - --role="porter-aks-restricted" \ - --scopes="/subscriptions/${PORTER_AZURE_SUBSCRIPTION_ID}" - ``` - - Save the output—you'll need these values: - - ```json - { - "appId": "00000000-0000-0000-0000-000000000000", - "displayName": "azure-porter-restricted-sp", - "password": "0000-0000-0000-0000-000000000000", - "tenant": "00000000-0000-0000-0000-000000000000" - } - ``` - - ### Grant API Permissions - - 1. In the Azure portal, search for **App registrations** - 2. Under **All applications**, select your new service principal - 3. Navigate to **API Permissions** - 4. Click **Add a permission** → **Microsoft Graph** → **Application permissions** - 5. Select these permissions: - - Application.ReadWrite.All - - Directory.ReadWrite.All - - Domain.Read.All - - Group.Create - - Group.ReadWrite.All - - RoleManagement.ReadWrite.Directory - - User.ReadWrite.All - 6. Click **Add permissions** - 7. Click **Grant admin consent for Default Directory** - - - - ## Enter Credentials in Porter - - In Porter, enter the following values from your service principal: - - | Field | Value | - |-------|-------| - | **Subscription ID** | Your Azure subscription ID | - | **Application (Client) ID** | The `appId` from your service principal | - | **Client Secret** | The `password` from your service principal | - | **Tenant ID** | The `tenant` from your service principal | - - ## Rotating Credentials - - Azure requires client secrets to expire every 365 days. When a secret expires, Porter can't manage infrastructure or deploy updates (existing workloads continue running). - - To refresh your client secret: - - 1. Visit [https://aka.ms/NewClientSecret](https://aka.ms/NewClientSecret) - 2. Select the app ID for your Porter service principal - 3. Generate a new client secret and copy the value - 4. In Porter, navigate to **Integrations** → **Azure** - 5. Update the **Password** field with the new value - - ## Revoking Access - - To revoke Porter's access: - - 1. First, delete any clusters through the Porter dashboard - 2. In the Azure portal, search for **App registrations** - 3. Find and delete the Porter service principal - 4. Optionally, delete the custom role definition - - This removes the service principal and prevents Porter from accessing your account. - From 96c06bed2ca349233bfb15ec49c6b76526290981 Mon Sep 17 00:00:00 2001 From: cathylin-wang Date: Thu, 18 Jun 2026 16:19:57 -0400 Subject: [PATCH 3/4] rm --- cloud-accounts/connecting-a-cloud-account.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/cloud-accounts/connecting-a-cloud-account.mdx b/cloud-accounts/connecting-a-cloud-account.mdx index 02f767d..7fa99e7 100644 --- a/cloud-accounts/connecting-a-cloud-account.mdx +++ b/cloud-accounts/connecting-a-cloud-account.mdx @@ -307,8 +307,6 @@ Before Porter can create a cluster, you need to grant it access to your cloud ac | **Application (Client) ID** | The `appId` from your app registration | | **Tenant ID** | Your Azure tenant ID (`az account show --query tenantId -o tsv`) | - No client secret is required — Porter authenticates by exchanging its OIDC token for short-lived Azure credentials. - ## Revoking Access To revoke Porter's access: From aaf2fa1a00fb06c818456f7979b55c8d0e33607c Mon Sep 17 00:00:00 2001 From: cathylin-wang Date: Fri, 19 Jun 2026 13:03:34 -0400 Subject: [PATCH 4/4] new docs --- cloud-accounts/connecting-a-cloud-account.mdx | 200 +++++------------- 1 file changed, 52 insertions(+), 148 deletions(-) diff --git a/cloud-accounts/connecting-a-cloud-account.mdx b/cloud-accounts/connecting-a-cloud-account.mdx index 7fa99e7..d27fabc 100644 --- a/cloud-accounts/connecting-a-cloud-account.mdx +++ b/cloud-accounts/connecting-a-cloud-account.mdx @@ -138,15 +138,24 @@ Before Porter can create a cluster, you need to grant it access to your cloud ac Porter connects to Azure using a service principal authenticated via [workload identity federation](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation) to manage your infrastructure. - ## Create the Service Principal + ## Prerequisites - You can create the service principal using our automated script (recommended) or manually. Both flows need the **OIDC subject** and **OIDC issuer** that Porter shows in the dashboard during the Azure cloud account connection — copy these before starting. + - Permissions to create app registrations, role definitions, and role assignments in your Azure subscription + - [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) and [`jq`](https://jqlang.github.io/jq/) installed - - - If you have the Azure CLI installed and authenticated (`az login`), run our setup script: + ## Connect Your Azure Subscription + + + + In the Porter dashboard, click **Connect a new account** and select **Azure**. Porter generates a one-time setup command with your OIDC subject and issuer already substituted. Keep this open — you'll paste it into your terminal in the next step. + + + Copy the commands shown in the dashboard and run it in your terminal. The commands look like: ```bash + # Authenticate the Azure CLI + az login + # Download the setup script curl -O https://raw.githubusercontent.com/porter-dev/docs/main/scripts/setup-azure-porter-wif.sh @@ -159,153 +168,48 @@ Before Porter can create a cluster, you need to grant it access to your cloud ac --issuer ``` - The script: - - Enables all required Azure resource providers - - Creates the custom `porter-aks-restricted` role - - Creates the app registration and service principal with proper permissions - - Adds Microsoft Graph API permissions - - Grants admin consent (if you have permissions) - - Adds the federated identity credential trusting Porter's OIDC issuer - - Displays the credentials needed for Porter + The script performs the initial setup in your Azure account: + + - Enables the required Azure resource providers: + - Microsoft.Capacity + - Microsoft.Compute + - Microsoft.ContainerRegistry + - Microsoft.ContainerService + - Microsoft.ManagedIdentity + - Microsoft.Network + - Microsoft.OperationalInsights + - Microsoft.OperationsManagement + - Microsoft.ResourceGraph + - Microsoft.Resources + - Microsoft.Storage + - Creates the custom `porter-aks-restricted` role and grants all subscription actions except: + - `Microsoft.Authorization/elevateAccess/Action` + - `Microsoft.Blueprint/blueprintAssignments/write` + - `Microsoft.Blueprint/blueprintAssignments/delete` + - `Microsoft.Compute/galleries/share/action` + - Creates the `azure-porter-federated-sp` app registration and matching service principal, then assigns the custom role at the subscription scope + - Adds these Microsoft Graph application permissions: + - Application.ReadWrite.All + - Directory.ReadWrite.All + - Domain.Read.All + - Group.Create + - Group.ReadWrite.All + - RoleManagement.ReadWrite.Directory + - User.ReadWrite.All + - Grants admin consent for the Graph permissions + - Adds a federated identity credential on the app registration trusting Porter's OIDC issuer (audience `api://AzureADTokenExchange`) + - Prints the Subscription ID, Application (Client) ID, and Tenant ID. Copy these for the next step + + Setup takes a few minutes. If the script fails to grant admin consent automatically, grant it manually in the Azure Portal: **App registrations** > **azure-porter-federated-sp** > **API permissions** > **Grant admin consent for Default Directory**. - - - - ### Enable Resource Providers - - Before creating the service principal, enable the required resource providers: - - 1. In the Azure portal, search for **Subscriptions** - 2. Select your subscription and click **Resource providers** - 3. Enable the following providers by selecting them and clicking **Register**: - - Microsoft.Capacity - - Microsoft.Compute - - Microsoft.ContainerRegistry - - Microsoft.ContainerService - - Microsoft.ManagedIdentity - - Microsoft.Network - - Microsoft.OperationalInsights - - Microsoft.OperationsManagement - - Microsoft.ResourceGraph - - Microsoft.Resources - - Microsoft.Storage - - Registration may take a few minutes per provider. Confirm all providers are enabled before proceeding. - - ### Create the Custom Role - - Run the following commands in the Azure Cloud Shell (Bash) or your local terminal with the Azure CLI: - - ```bash - # Set your subscription ID - PORTER_AZURE_SUBSCRIPTION_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - - # Create the role - envsubst << EOF | az role definition create --role-definition @- - { - "assignableScopes": ["/subscriptions/${PORTER_AZURE_SUBSCRIPTION_ID}"], - "description": "Grants Porter access to manage resources for an AKS cluster.", - "id": "/subscriptions/${PORTER_AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Authorization/roleDefinitions/porter-aks-restricted", - "isCustom": true, - "name": "porter-aks-restricted", - "permissions": [ - { - "actions": ["*"], - "dataActions": [], - "notActions": [ - "Microsoft.Authorization/elevateAccess/Action", - "Microsoft.Blueprint/blueprintAssignments/write", - "Microsoft.Blueprint/blueprintAssignments/delete", - "Microsoft.Compute/galleries/share/action" - ], - "notDataActions": [] - } - ], - "roleName": "Contributor", - "roleType": "BuiltInRole", - "type": "Microsoft.Authorization/roleDefinitions" - } - EOF - ``` - - ### Create the Service Principal - - ```bash - # Create the app registration and capture its Application (Client) ID - APP_ID=$(az ad app create --display-name "azure-porter-federated-sp" --query appId -o tsv) - - # Create the matching service principal - az ad sp create --id "$APP_ID" - - # Wait for the service principal to propagate before assigning a role to it - sleep 10 - - # Assign the custom role at the subscription scope - az role assignment create \ - --assignee "$APP_ID" \ - --role "porter-aks-restricted" \ - --scope "/subscriptions/${PORTER_AZURE_SUBSCRIPTION_ID}" - ``` - - Save the `APP_ID` — you'll enter it in Porter as the Application (Client) ID. Get your Tenant ID with `az account show --query tenantId -o tsv`. - - ### Add the Federated Identity Credential - - Trust Porter's OIDC issuer to exchange tokens for this app registration. Use the **OIDC subject** and **OIDC issuer** shown in Porter: - - ```bash - # Values copied from the Porter dashboard - PORTER_OIDC_SUBJECT= - PORTER_OIDC_ISSUER= - - # Derive a name from the project ID in the subject - PROJECT_ID="${PORTER_OIDC_SUBJECT##*-}" - - az ad app federated-credential create \ - --id "$APP_ID" \ - --parameters "{ - \"name\": \"porter-project-${PROJECT_ID}\", - \"issuer\": \"${PORTER_OIDC_ISSUER}\", - \"subject\": \"${PORTER_OIDC_SUBJECT}\", - \"audiences\": [\"api://AzureADTokenExchange\"] - }" - ``` - - - Azure can take a few minutes to propagate the federated credential. If Porter rejects the first connection attempt, wait a moment and retry. - - - ### Grant API Permissions - - 1. In the Azure portal, search for **App registrations** - 2. Under **All applications**, select your new service principal - 3. Navigate to **API Permissions** - 4. Click **Add a permission** → **Microsoft Graph** → **Application permissions** - 5. Select these permissions: - - Application.ReadWrite.All - - Directory.ReadWrite.All - - Domain.Read.All - - Group.Create - - Group.ReadWrite.All - - RoleManagement.ReadWrite.Directory - - User.ReadWrite.All - 6. Click **Add permissions** - 7. Click **Grant admin consent for Default Directory** - - - - ## Enter Credentials in Porter - - In Porter, enter the following values from your service principal: - - | Field | Value | - |-------|-------| - | **Subscription ID** | Your Azure subscription ID | - | **Application (Client) ID** | The `appId` from your app registration | - | **Tenant ID** | Your Azure tenant ID (`az account show --query tenantId -o tsv`) | + + + Paste the **Subscription ID**, **Application (Client) ID**, and **Tenant ID** the script printed back into Porter to finish the connection. + + ## Revoking Access