Skip to main content Skip to content

Cloud Accounts

Connect AWS, GCP, and Azure accounts to ZopNight. Supported auth methods, permission levels, billing upgrade, cluster registration, and OAuth flow.

10 min read Last updated: 

Connect your AWS, GCP, or Azure accounts to enable resource discovery and scheduling.

Supported Providers

Amazon Web Services (AWS)

Auth MethodIDDescription
Static Access Keysstatic_keysIAM access key ID and secret access key
Assume Roleassume_roleKeyless role federation: ZopNight assumes your IAM role with a web identity token (AssumeRoleWithWebIdentity). No external ID is used
Temporary Credentialstemporary_credentialsShort-lived STS credentials

Google Cloud Platform (GCP)

Auth MethodIDDescription
Service Accountservice_accountJSON key file for a GCP service account
OAuth 2.0oauthThree-step OAuth flow with encrypted token exchange

Microsoft Azure

Auth MethodIDDescription
Service Principalservice_principalApp registration with client ID, secret, and tenant ID
Workload Identity Federationworkload_identity_federationFederated OIDC identity, no secrets stored

Permission Levels

LevelDiscoverySchedulingExecution
read_onlyYesYesNo
read_writeYesYesYes

Connected & last-synced visibility

Each cloud account card shows the date it was first connected and the most recent successful sync — broken down per provider service. Useful for spotting accounts where a credential rotation or a permissions drop has silently halted discovery.

Billing upgrade flow

If you connected an account in read_only mode without billing access, you can upgrade in three clicks without re-running setup. ZopNight detects the gap and surfaces a banner on the Dashboard with a per-account Fix button.

  • Provider-specific guide — the upgrade drawer renders the exact IAM/role JSON for AWS or Azure based on your existing auth method.
  • AWS one-click CloudFormation — for accounts using assume_role, ZopNight generates a CloudFormation template that adds ce:GetCostAndUsage and ce:GetCostAndUsageWithResources to your existing role. No manual policy editing.
  • Verify: the verify step checks billing access for the account and polls until a terminal state is reached, with a real-time spinner during the check.
  • GCP excluded — billing is configured at the billing-account level, not the project, so the upgrade flow doesn’t apply.
POST /billing/verify

Verify billing access for one cloud account. Body: {cloudAccountId, provider}. Returns that account's sync status.

GET /billing/sync-status

Billing sync status for every cloud account in the org. Poll it to follow a verification to a terminal state, such as success, no_permission, failed or skipped.

See Billing for the request and response fields.

Azure AI agents and Copilot credits

Cost Reports → AI Spend → Agents and AI Estate → AI Gateway show the Azure AI Foundry agents in a connected subscription: which exist, which are used, and Microsoft’s estimated model cost for each. They also show Copilot credits billed per billing policy. Both read your existing Azure connection; there is nothing new to install.

Grant on the service principalWhat it adds
Reader on the subscription (already part of setup)Foundry accounts and projects, published agents, usage metrics, and your Copilot billing policies
Cost Management Reader (part of billing access)Billed Azure AI spend and Copilot credits
Zopnight AI Agents Reader (custom role, below)Every agent, including unpublished ones, with model, tools, identity and usage

Without the custom role, ZopNight still lists your published agents. Their details read Details hidden, and a Grant the AI Agents Reader role button opens the steps.

The custom role adds one read-only data action and nothing else. It cannot create, change or run an agent. Azure’s action also covers reading threads and messages; ZopNight only lists agents, and never stores an agent’s instructions. Create it in your subscription and assign it to the same service principal:

Terminal window
{
"properties": {
"roleName": "Zopnight AI Agents Reader",
"description": "Custom role for Zopnight AI Agents Reader on ZopNight",
"assignableScopes": ["/subscriptions/<subscription-id>"],
"permissions": [
{
"actions": [],
"notActions": [],
"dataActions": ["Microsoft.CognitiveServices/accounts/AIServices/agents/read"],
"notDataActions": []
}
]
}
}

Create Cloud Account

POST /cloud-accounts

Connect a new cloud account.

AWS Example (Static Keys)

Terminal window
curl -X POST https://api.zop.dev/cloud-accounts \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"provider": "aws",
"cloudAccountId": "123456789012",
"name": "Production AWS",
"authMethod": "static_keys",
"permissionLevel": "read_write",
"credentials": {
"accessKeyId": "AKIAIOSFODNN7EXAMPLE",
"secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLE"
}
}'

AWS Example (Assume Role)

Terminal window
curl -X POST https://api.zop.dev/cloud-accounts \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"provider": "aws",
"cloudAccountId": "123456789012",
"name": "Production AWS",
"authMethod": "assume_role",
"permissionLevel": "read_write",
"credentials": {
"roleArn": "arn:aws:iam::123456789012:role/ZopNightRole"
}
}'

GCP Example (Service Account)

Terminal window
curl -X POST https://api.zop.dev/cloud-accounts \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"provider": "gcp",
"cloudAccountId": "my-gcp-project-id",
"name": "Production GCP",
"authMethod": "service_account",
"permissionLevel": "read_write",
"credentials": {
"serviceAccountJson": "{...service account key JSON...}"
}
}'

Azure Example (Service Principal)

Terminal window
curl -X POST https://api.zop.dev/cloud-accounts \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"provider": "azure",
"cloudAccountId": "subscription-id",
"name": "Production Azure",
"authMethod": "service_principal",
"permissionLevel": "read_write",
"credentials": {
"clientId": "app-client-id",
"clientSecret": "app-client-secret",
"tenantId": "azure-tenant-id"
}
}'
Response
{
"data": {
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"orgId": "3f6c2a9e-8b1d-4c7e-9f2a-1d5e6b7c8a90",
"provider": "aws",
"cloudAccountId": "123456789012",
"name": "Production AWS",
"authMethod": "static_keys",
"permissionLevel": "read_write",
"status": "active",
"createdAt": "2025-01-15T10:30:00Z",
"updatedAt": "2025-01-15T10:30:00Z"
}
}

List Cloud Accounts

GET /cloud-accounts

List all connected cloud accounts.

Get Cloud Account

GET /cloud-accounts/{accountID}

Get a specific cloud account by ID.

Update Cloud Account

PUT /cloud-accounts/{accountID}

Update cloud account name, permission level, credentials, or authentication method — all in place, without recreating the account.

Terminal window
curl -X PUT https://api.zop.dev/cloud-accounts/1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Renamed AWS Account",
"permissionLevel": "read_write"
}'

Change the Authentication Method (in place)

You can switch a connected account from one authentication method to another — for example AWS access keys → keyless role federation — without deleting and recreating it. The account keeps the same identity, so its resources, groups, recommendations, cost history, schedules, and configuration all stay intact.

Supported switches

  • AWS — any-to-any across static_keys, temporary_credentials, and assume_role.
  • Azure — service_principal ↔ workload_identity_federation (a tenant-scoped parent cascades the change to its subscription children).
  • GCP — not yet available in place; oauth needs an interactive Google consent flow, so switching to/from it still uses disconnect + reconnect.

In the UI, open the account’s Edit drawer → Update credentials. This opens a guided 3-step wizard — Auth Method → Setup Guide (create the credentials, including AWS one-click CloudFormation) → Enter Credentials — the same steps used by the Connect Cloud Account wizard. Step 1 preselects the current method (marked Current): keep it and save to rotate the credentials, or pick a different method to switch. Saving re-verifies and re-keys the same account. (GCP and Databricks keep an inline credential form instead of the wizard, since they have no in-place method change.)

Via the API, send authMethod alongside the new credentials on the same PUT endpoint:

Terminal window
curl -X PUT https://api.zop.dev/cloud-accounts/1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"authMethod": "assume_role",
"credentials": {
"roleArn": "arn:aws:iam::123456789012:role/ZopNightRole"
}
}'

Same-account safety. The new credentials must resolve to the same cloud identity as the account (AWS 12-digit account ID via STS; Azure subscription membership; same tenant for tenant-scoped parents). If they point at a different account the request is rejected with 400 and nothing changes — an account can only be re-authenticated, never silently repointed. After a successful change ZopNight re-fetches credentials and re-runs the permission probe automatically.

Rotation is verified too. A same-method credential update (rotation) runs the exact same live check before storing — the new credentials must authenticate and resolve to the same account. This means a wrong or foreign credential is rejected with 400 instead of silently overwriting the working credential and breaking discovery.

Delete Cloud Account

DELETE /cloud-accounts/{accountID}

Disconnect a cloud account. Associated resources will be soft-deleted.

GCP OAuth Flow

For GCP accounts, ZopNight supports a three-step OAuth flow as an alternative to service account keys. Tokens are encrypted with AES-256-GCM and are never exposed in plaintext.

1. Get OAuth URL

GET /connect/gcp/oauth-url

Returns a Google OAuth consent URL. Redirect the user to this URL.

2. Exchange Code

POST /connect/gcp/oauth-exchange

Exchange the authorization code for an encrypted token reference.

3. Finalize

POST /connect/gcp/oauth-finalize

Finalize the connection by selecting a GCP project and setting permissions.

Cluster Access for Deployment Spaces

Once a cloud account is connected, you can register specific Kubernetes clusters (EKS, GKE, AKS) so ZopNight can mint short-lived kubeconfigs for them. Registering a cluster is the prerequisite for promoting it to a Deployment Space — the unit ZopNight provisions and deploys against.

GET /cloud-accounts/{accountID}/clusters

List clusters discovered in this cloud account, with their registration status.

Response
{
"data": [
{
"name": "prod-eks",
"region": "us-east-1",
"type": "aws-eks",
"registered": true,
"registeredAt": "2026-04-15T08:00:00Z"
},
{
"name": "staging-eks",
"region": "us-east-1",
"type": "aws-eks",
"registered": false
}
]
}
PUT /cloud-accounts/{accountID}/clusters/{region}/{clusterName}/access

Register a cluster for kubeconfig access.

Request
curl -X PUT "https://api.zop.dev/cloud-accounts/1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d/clusters/us-east-1/prod-eks/access" \
-H "Authorization: Bearer <token>"
DELETE /cloud-accounts/{accountID}/clusters/{region}/{clusterName}/access

Deregister a cluster. Existing deployment spaces that target it will fail to deploy until re-registered.

Azure Workload Identity Federation

For secretless Azure authentication, you add a federated credential to your Azure app registration that trusts ZopNight’s identity. In Azure, open the app’s Certificates & secrets → Federated credentials, choose Other Issuer, and enter:

  • Issuer: https://accounts.google.com
  • Subject identifier: the ZopNight identity shown in the in-app setup guide for Workload Identity Federation

Then connect the account with authMethod: "workload_identity_federation".

See Cloud Support Matrix for the complete list of discoverable and executable resource types per provider.

Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·