> ## Documentation Index
> Fetch the complete documentation index at: https://docs.porter.run/llms.txt
> Use this file to discover all available pages before exploring further.

# Connecting a cloud account

> Grant Porter access to your AWS, GCP, or Azure account using IAM roles, Workload Identity Federation, or service principals 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.

<Tabs>
  <Tab title="AWS">
    Porter uses AWS IAM role assumption via the `AssumeRole` [operation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html) to access your account. You create a role in your AWS account and declare that you trust Porter to assume it. This eliminates static credentials and makes access easy to revoke.

    ## Create the IAM Role

    <Steps>
      <Step title="Enter your AWS Account ID">
        After selecting AWS as your cloud provider, log into your [AWS Console](https://console.aws.amazon.com) and find your 12-digit Account ID in the top-right corner.

        Enter this ID in Porter and click **Grant Permissions**.
      </Step>

      <Step title="Create the CloudFormation stack">
        Porter opens the AWS CloudFormation console in a new tab to create a stack that provisions the `porter-manager` IAM role.

        <Warning>
          If the popup is blocked, check your browser settings and allow popups from Porter.
        </Warning>

        Scroll to the bottom of the CloudFormation page, check the **I acknowledge that AWS CloudFormation might create IAM resources** box, and click **Create Stack**.

        Wait for the stack creation to complete (this takes a few minutes).
      </Step>
    </Steps>

    <Info>
      The IAM role must remain in your AWS account for Porter to manage your infrastructure. Deleting it will prevent Porter from making changes.
    </Info>

    ## Permissions Granted

    The CloudFormation stack creates an IAM role with permissions to:

    * Create and manage EKS clusters
    * Create and manage VPCs, subnets, and security groups
    * Create and manage ECR repositories
    * Create and manage IAM roles for cluster operations
    * Request service quota increases

    <Info>
      If you need Porter to operate with more restricted permissions, contact us through the support widget to inquire about Porter Enterprise.
    </Info>

    ## Revoking Access

    To revoke Porter's access:

    1. First, delete any clusters through the Porter dashboard
    2. Navigate to **CloudFormation Stacks** in your AWS console
    3. Select the stack named `PorterRole` and click **Delete**

    This removes the IAM role and prevents Porter from accessing your account.
  </Tab>

  <Tab title="GCP">
    Porter connects to GCP using [Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation). Workload Identity Federation offers a mechanism for Porter to connect with your GCP project without requiring any static keys. Setup runs in [Google Cloud Shell](https://cloud.google.com/shell) with a single command Porter generates for your project.

    ## Prerequisites

    Your GCP project needs an active [billing account](https://console.cloud.google.com/billing) attached. Porter cannot provision infrastructure without one.

    The Google account running the setup must have these project-level roles (or `roles/owner`, which covers all of them):

    * `roles/serviceusage.serviceUsageAdmin`
    * `roles/iam.serviceAccountAdmin`
    * `roles/resourcemanager.projectIamAdmin`
    * `roles/iam.workloadIdentityPoolAdmin`
    * `roles/storage.admin`

    ## Connect Your GCP Project

    <Steps>
      <Step title="Enter your GCP Project ID">
        In Porter, select GCP. Enter your [GCP project ID](https://console.cloud.google.com) (visible at the top of any page in the GCP Console) and click **Connect**. Porter generates a one-time setup command scoped to this integration.
      </Step>

      <Step title="Run the setup in Cloud Shell">
        In the Porter dashboard:

        1. Copy the command shown in the **Run Setup in Cloud Shell** panel.
        2. Click **Open Cloud Shell** to launch a new tab with the [porter-dev/gcp-onboarding](https://github.com/porter-dev/gcp-onboarding) repository pre-loaded.
        3. Cloud Shell will warn that the repository is from an untrusted source. Click **Trust** to continue. The repository is open source so you can review the Terraform before approving.
        4. Paste the command into the shell and press Enter.

        The script runs Terraform in your project and performs the initial setup:

        * Enables five Google APIs: Cloud Resource Manager, IAM, IAM Credentials, STS, and Service Usage
        * Creates a `porter-manager-*` service account that Porter impersonates
        * Creates a `porter-pool-*` Workload Identity Pool with a trust policy scoped to your project
        * Grants three bootstrap IAM roles to the service account so Porter can finish the rest of the configuration itself: `roles/serviceusage.serviceUsageAdmin`, `roles/resourcemanager.projectIamAdmin`, and `roles/iam.serviceAccountAdmin`

        Setup takes about 30 seconds.
      </Step>

      <Step title="Wait for verification">
        Porter's dashboard polls the connection automatically. Once the bootstrap completes, Porter takes over the heavier configuration on your behalf. It enables the remaining APIs needed for cluster provisioning (Compute, Kubernetes Engine, Artifact Registry, Secret Manager, and others) and grants the matching per-service roles to the `porter-manager-*` service account (Compute Admin, Kubernetes Engine Admin, Artifact Registry Admin, Secret Manager Admin, and others). Once everything is provisioned, the cloud account is marked connected and the status banner turns green.

        The full Terraform module is open source if you want to inspect every resource Porter creates: [porter-dev/gcp-onboarding](https://github.com/porter-dev/gcp-onboarding).
      </Step>
    </Steps>

    ## Migrating from a Service Account JSON

    If you previously connected GCP using a service account JSON key, you can switch to Workload Identity Federation with no downtime:

    1. In Porter, navigate to **Integrations** → **Cloud accounts** and select your GCP account.
    2. Click **Migrate to Workload Identity Federation** in the banner at the top of the page.
    3. Follow the same Cloud Shell flow above.

    Your existing clusters keep authenticating with the JSON key while the new federation is being verified. Once verified, Porter swaps the credential atomically. There is no service interruption.

    ### After Migration

    Workload Identity Federation is now the active connection between Porter and your GCP project, but your previous service account and its JSON key are still present in your project until you remove them. To finish the migration:

    1. In the [GCP Console](https://console.cloud.google.com), open **IAM & Admin** → **Service Accounts**.
    2. Find your legacy service account (the one whose key you previously uploaded to Porter — typically named `porter-manager`, separate from the new `porter-manager-*` account created during federation).
    3. Delete its JSON key, or delete the entire service account.

    Porter no longer needs the legacy account once federation is active. Leaving it in place means an unrotated long-lived key continues to exist in your project.

    ## Revoking Access

    To disconnect Porter from your GCP project:

    1. First, delete any clusters through the Porter dashboard.
    2. In the [GCP Console](https://console.cloud.google.com), navigate to **IAM & Admin** → **Workload Identity Federation** and delete the `porter-pool-*` Workload Identity Pool. This immediately invalidates all federated tokens.

    Optionally, also delete the `porter-manager-*` service account under **IAM & Admin** → **Service Accounts** for full cleanup.
  </Tab>

  <Tab title="Azure">
    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.

    <AccordionGroup>
      <Accordion title="Option 1: Automated setup (recommended)">
        If you have the Azure CLI installed and authenticated (`az login`), run our setup script:

        ```bash theme={null}
        # 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

        <Warning>
          Re-running this script (or `az ad sp create-for-rbac`) against an existing service principal **resets its client secret**, which immediately breaks authentication for **every** Porter cloud account using that service principal. To rotate the secret safely, add a new one instead (`az ad app credential reset --id <appId> --append`) and update it in all affected Porter accounts. To avoid a shared-secret blast radius, use a distinct service principal per environment.
        </Warning>

        <Info>
          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**.
        </Info>
      </Accordion>

      <Accordion title="Option 2: Manual setup">
        ### 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 theme={null}
        # 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.",
            "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": []
                }
            ]
        }
        EOF
        ```

        ### Create the Service Principal

        ```bash theme={null}
        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 theme={null}
        {
          "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**
      </Accordion>
    </AccordionGroup>

    ## 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

    <Warning>
      Generate a **new** secret rather than deleting the existing one, so in-flight operations keep working during the swap. If this service principal is shared across multiple Porter cloud accounts or subscriptions, update the new secret in **all** of them. Do not re-run the setup script to rotate — `az ad sp create-for-rbac` resets the secret and disconnects every account using the service principal.
    </Warning>

    ## 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.
  </Tab>
</Tabs>
