<@ULVA73B9P> I'm on the Prefect Cloud Starter plan...
# ask-marvin
h
@Marvin I'm on the Prefect Cloud Starter plan and I'm trying to setup CI/CD with GitHub Actions for deploying flows. We have problems using Service Accounts and API Keys. We have created a Service Account on the "Account" level, not "Workspace" level. But we can not use the API key to authenticate. Is this supported and/or can you help us configure this?
m
thought for 158.1 seconds
Short answer: yes—this is supported on the Starter plan. In Prefect 3.x, Service Accounts are created at the Account level, but they must be added to each Workspace you want them to access. If the Service Account isn’t shared with the workspace (and given the right role), authentication will “work” but you’ll be unauthorized to do anything in that workspace. What to check and how to set it up 1) Add the Service Account to the workspace - In the Prefect Cloud UI, switch to the target workspace. - Go to Settings > Access (Members). - Add/Share the Service Account to this workspace and assign a role that can manage deployments and work pools (e.g., an editor-level role). - Verify it can see the work pool you’ll deploy to. 2) Choose one of the two auth patterns in CI Option A: Use prefect cloud login (no need to set API URL) - You’ll need the service account API key and the workspace handle in the form account_handle/workspace_handle. - Example (GitHub Actions):
Copy code
name: Deploy Prefect
on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      PREFECT_API_KEY: ${{ secrets.PREFECT_API_KEY }}  # Service Account key
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"

      - name: Install Prefect
        run: pip install -U prefect

      - name: Login to Prefect Cloud
        run: prefect cloud login --key "$PREFECT_API_KEY" --workspace "<account_handle>/<workspace_handle>"

      - name: Deploy
        run: prefect deploy
Option B: Use environment variables (no CLI login) - Set both
PREFECT_API_KEY
and
PREFECT_API_URL
. -
PREFECT_API_URL
must be the workspace-scoped API: https://api.prefect.cloud/api/accounts/&lt;ACCOUNT-ID&gt;/workspaces/&lt;WORKSPACE-ID> - You can get the IDs from your app URL: https://app.prefect.cloud/account/&lt;ACCOUNT-ID&gt;/workspace/&lt;WORKSPACE-ID&gt;/… - Example (GitHub Actions):
Copy code
name: Deploy Prefect
on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      PREFECT_API_KEY: ${{ secrets.PREFECT_API_KEY }}
      PREFECT_API_URL: ${{ secrets.PREFECT_API_URL }}
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"

      - name: Install Prefect
        run: pip install -U prefect

      - name: Deploy
        run: prefect deploy
Notes and common pitfalls - Service Accounts are always created at the Account level in Prefect 3.x; that’s expected. You must explicitly share them with each workspace and assign the correct workspace role. - 401 Unauthorized typically means the key is invalid or mistyped. 403 Forbidden typically means the Service Account is not shared with the workspace or lacks sufficient role permissions. - Make sure you run
prefect deploy
from a project containing a valid
prefect.yaml
, or provide an explicit entrypoint if you’re not using a project. - Starter plan supports Service Accounts for CI/CD; there’s no plan restriction blocking this workflow. Docs for reference - Service Accounts: Service accounts - Connect to Cloud (API key, profiles, URL): Connect to Cloud - CI/CD with GitHub Actions: CI/CD deployments If it’s still failing, can you share: - The exact error message you’re seeing - Which auth pattern you’re using (cloud login vs env vars) - Confirmation that the Service Account was added to the target workspace and its role - The workspace handle or the account/workspace IDs you’re targeting I’m happy to help debug your YAML or commands once I see those details.
h
I added my workspace to the service account when I created it, but I can't configure membership on the workspace UI as this is a PRO only feature
@Marvin The response we got was Response: {'detail': 'IP address x.x.x.x is not allowed for account yyyy or account does not exist.'}
m
thought for 94.9 seconds
Thanks—that error pinpoints the issue. It’s coming from Prefect Cloud’s IP allowlist: your account has IP allowlisting enabled, and the GitHub Actions runner’s egress IP isn’t on the list. The request is being blocked before your Service Account/API key is even evaluated. What this means - When IP allowlisting is enabled and non-empty, only requests from listed IPs can access your account’s API/UI. - GitHub-hosted runners use dynamic IPs that change frequently, so they typically won’t work with an IP allowlist unless you switch to self-hosted runners with a static egress IP or disable the allowlist. Your options 1) Disable the allowlist (simplest for GitHub-hosted runners) - From a machine that’s already allowed (e.g., your laptop/VPN), log in and disable it:
Copy code
prefect cloud login --key "<YOUR_ADMIN_OR_SERVICE_ACCOUNT_KEY>" --workspace "<account_handle>/<workspace_handle>"
prefect cloud ip-allowlist ls          # sanity check current entries
prefect cloud ip-allowlist disable     # turn off enforcement
2) Keep the allowlist and use a static egress IP - Run your CI/CD from a self-hosted runner or any environment with a stable, known egress IP (or NAT gateway). - Then add that IP (or a CIDR) to the allowlist:
Copy code
prefect cloud login --key "<YOUR_ADMIN_OR_SERVICE_ACCOUNT_KEY>" --workspace "<account_handle>/<workspace_handle>"
prefect cloud ip-allowlist add <IP-or-CIDR> --description "CI runner"
prefect cloud ip-allowlist enable
Notes and gotchas - You must perform allowlist changes from a currently allowed IP (to prevent lockouts). - GitHub-hosted runners are not suitable for strict IP allowlisting due to dynamic IPs. - After resolving the network restriction, make sure the Service Account is shared with the target workspace and has a role that can manage deployments. - For CI auth, either: - Use
prefect cloud login --key ... --workspace <account_handle>/<workspace_handle>
, or - Set
PREFECT_API_KEY
and
PREFECT_API_URL
to the workspace URL
<https://api.prefect.cloud/api/accounts/<ACCOUNT-ID>/workspaces/<WORKSPACE-ID>>
. Docs - Secure access by IP address: IP allowlist - Connect to Cloud: Connect to Cloud - CI/CD deployments: CI/CD deployments Quick questions so I can tailor the next steps: - Are you using GitHub-hosted runners or self-hosted? - Do you want to keep IP allowlisting enabled, or is disabling it acceptable for your workflow?
h
@Marvin I thought IP allowlists where an Enterprise only feature? We're on the Starter plan
m
thought for 51.9 seconds
Great question. Yes—IP allowlisting is an Enterprise security feature. It isn’t part of the Starter plan by default. Why you’re seeing that error anyway - That specific message (“IP address x.x.x.x is not allowed for account … or account does not exist”) is returned when: 1) IP allowlisting is enabled on the account and your current IP is not on the allowlist, or 2) The account/workspace you’re targeting is wrong (bad account/workspace ID or handle) It’s possible the allowlist was enabled previously (e.g., during a trial or by request) and is still active, even if you’re now on Starter. Or the error could be due to a misconfigured API URL/handle. Let’s verify which case it is 1) Check IP allowlist status from an allowed network (e.g., your laptop/VPN if that works):
Copy code
prefect cloud login --key "<API_KEY>" --workspace "<account_handle>/<workspace_handle>"
prefect cloud ip-allowlist ls
- If you see entries and it’s enabled, that explains the block. - You can temporarily turn it off:
Copy code
prefect cloud ip-allowlist disable
Note: these commands work only if the feature is enabled on your account and you’re connecting from an allowed IP. 2) Double-check your targeting: - If you’re using env vars, ensure
PREFECT_API_URL
is the workspace-scoped URL: https://api.prefect.cloud/api/accounts/&lt;ACCOUNT-ID&gt;/workspaces/&lt;WORKSPACE-ID> - Or, use:
Copy code
prefect cloud login --key "<API_KEY>" --workspace "<account_handle>/<workspace_handle>"
A wrong account/workspace will also trigger that error. If you do need an IP allowlist - GitHub-hosted runners won’t work reliably (dynamic IPs). Use a self-hosted runner or another CI environment with a stable egress IP that you can add to the allowlist. Docs - IP allowlist: IP allowlist - Connect to Cloud: Connect to Cloud If you’d like, share: - Whether
prefect cloud ip-allowlist ls
shows entries/enabled - How you’re authenticating (env vars vs
prefect cloud login
) - The
PREFECT_API_URL
you’re using (with IDs redacted) …and I can help you zero in on the fix. If the allowlist is enabled unexpectedly on your Starter account and you can’t disable it, we can loop in Prefect Support to remove it on the backend.