Skip to main content

Use a service account for CI and automation

Goal​

You'll create a service account (dqsa_…), scope it to the workspace your pipeline works in, and use its token from CI, an orchestrator, the SDKs or the MCP server. A service account is the identity for automation: unlike a personal API key, it isn't tied to a person, so it keeps working when the person who set up the pipeline changes role or leaves.

Prereqs​

  • A super admin account. Creating a service account needs the manage-service-accounts permission, and a caller can only hand out authority it holds, so in practice a super admin creates them.
  • You know which workspace the pipeline reads and writes.

Steps​

  1. Open Settings → Service Accounts and click Create service account.

  2. Name it after what uses it (dbt-ci, airflow-nightly), so the audit log and the list say who did what.

  3. Pick a role. The role decides what the service account may do, exactly as it does for a member. For a pipeline that registers assets, creates rules and runs validations, pick Editor. For a reporting job that only reads results, pick Viewer.

  4. Pick the workspace. Editor, viewer and workspace admin service accounts are pinned to one workspace. See What a service account can reach.

  5. Confirm your password if prompted. Creating a service account is step-up gated. If you sign in through SSO, the prompt offers Re-authenticate with provider instead.

  6. Copy the token now. The raw dqsa_… token is shown once. Measured Cloud stores only a hash. Put it straight into your CI secret store. If you lose it, revoke the service account and create a new one.

Use it​

Send the token as a Bearer token. It works on the same endpoints a member uses, through either path:

  • the workspace path, /api/v{1,2}/organizations/{org_id}/workspaces/{workspace_id}/…;
  • the org path, /api/v{1,2}/organizations/{org_id}/…, where the service account sees only its own workspace's rows.

Run a validation from CI:

curl -X POST \
-H "Authorization: Bearer $DQSA_TOKEN" \
"https://dq.example.com/api/v2/organizations/$ORG_ID/workspaces/$WS_ID/validations/$VALIDATION_ID/run"

The 202 response carries execution_run_id and parent_result_id, which you can poll. A run started by a service account is recorded with trigger api.

Ingest dbt artifacts after dbt build:

curl -X POST \
-H "Authorization: Bearer $DQSA_TOKEN" -H "Content-Type: application/json" \
"https://dq.example.com/api/v1/organizations/$ORG_ID/workspaces/$WS_ID/dbt/ingest" \
-d @payload.json

The SDKs and the Airflow and Dagster providers send their key as a Bearer token, so a dqsa_… token works wherever they take a dqk_… key. (With the dq-cloud-airflow-provider package, put the token in the connection's extra as api_key: that package treats a password that doesn't start with dqk_ as a login password.) The MCP server accepts only personal API keys.

What a service account can reach​

A service account has its own role and scope. It reaches exactly the workspaces its scope grants, and inside them it can do what its role allows:

RoleScopeReaches
Super adminOrg-wide (never pinned)Every workspace in the organization.
Technical adminOrg-wide (never pinned)Data sources in every workspace, and nothing else on the workspace surface.
Workspace adminOne workspaceThat workspace only, with workspace-admin rights (including deletes that don't need step-up).
EditorOne workspace, or one team (API only)That workspace only. Register data assets (including dbt ingest), create and edit rules and validations, run validations, and read results, alerts and incidents.
ViewerOne workspace, or one team (API only)That workspace only, read-only.
Team adminOne teamTeam membership management only. The role has no data permissions, so it can't read or run anything.

Workspace scoping is enforced twice, on the route and on every row a request reads:

  • A request for another workspace answers 403 with Service account is not scoped to this workspace.
  • A list through the org path returns only rows from the service account's workspace, and a row of another workspace answers 404.
  • A service account pinned to a team reaches that team's workspace and follows the same team rules as a team member: it sees workspace-shared rows and its own team's rows, but not rows restricted to another team.

The role still applies inside the scope. A viewer service account gets 403 Missing permission: … when it tries to create or run something.

An editor or viewer service account must be pinned. One with no workspace or team can't be created, and reaches nothing.

What a service account can't do​

  • Anything step-up gated. Step-up actions need an interactive user session with a recent password or SSO proof, and a long-lived token can never provide one. That covers creating or revoking credentials (including other service accounts), creating, editing or deleting a data source, deleting a validation, recycle-bin purges, SSO and membership changes, and org settings. The full list is in Step-up auth for sensitive actions. A service account gets 403 with a message that says step-up needs an interactive session. It doesn't get the 401 step_up_required challenge, because re-authenticating can't help it. Do these actions in the app.
  • Org-level management while pinned. A workspace- or team-pinned service account can't manage org-level resources such as invites, domains or team rosters, whatever its role.
  • Comment. Comments on results and incident timelines are attributed to a person, so they need a user session.
  • Governance flips. Changing an asset's Restricted flag or its sample retention needs a person who is workspace admin, unless the service account is a super admin.

Revoke it​

In Settings → Service Accounts, click Revoke on the row (or DELETE /api/v1/organizations/{org_id}/service-accounts/{id}). Revoking is step-up gated and takes effect at once: the cached lookup is cleared, and the next request with the token answers 401.

Verify​

  • The service account appears in Settings → Service Accounts with its role and its scope (Workspace-scoped, Team-scoped or Org-wide).
  • GET /api/v2/organizations/$ORG_ID/workspaces/$WS_ID/validations with the token returns 200. The same call for another workspace returns 403 (unless the service account is a super admin).
  • After you revoke it, the same call returns 401.