Service principals
A service principal is a non-person identity for automation, such as a deployment pipeline. It holds one role, can be limited to application groups, and signs in with client credentials. Use it to keep application and group definitions in source control and apply them through the API.
What a service principal can and can’t do
A service principal gets the permissions of its role and scope, and no more. The same application, group, and audit-engagement checks apply as for a person with that role.
It can hold the Developer, Governance Engineer, or Compliance Officer role. Administrator, Business Owner, and Auditor authority belongs to people.
Whatever its role says, a service principal can’t:
- record a human review decision or take on review work;
- decide, extend, or revoke a policy exception;
- approve a rule deployment, a production change request, or its own change;
- activate, deactivate, roll back, or delete a rule;
- issue or resume an emergency stop;
- manage people, roles, identity provisioning, sign-in settings, or service principals.
VeriProof refuses these requests on the server and records the refusal in the access log. Audit records for everything a service principal does name it as the actor.
Create a service principal
Open Settings
In Settings > Team > Service principals, select Add service principal. You need the Administrator role.
Choose the role and scope
Enter a name that identifies the pipeline. Choose the role, and select application groups to limit the service principal to those groups’ applications.
Choose how it signs in
- Client secret: VeriProof shows the secret once. It’s stored only as a hash and expires after the lifetime you choose, up to 365 days.
- Microsoft Entra workload identity: enter the Entra tenant ID and the object ID of the managed identity or app registration. The pipeline then exchanges its own Entra token instead of storing a secret.
A service principal can have two active secrets at once. To rotate, add a new secret, update the pipeline, then revoke the old secret. Removing a service principal revokes its secrets and stops it immediately.
Get an access token
Request a token with the OAuth 2.0 client credentials grant. Tokens last 10 minutes. VeriProof re-checks the service principal, its credential, and its role on every request, so a revoked secret or a removed service principal stops working at once.
curl -s -X POST "$VERIPROOF_API_URL/v1/auth/service-principals/token" \
-d grant_type=client_credentials \
-d client_id="$VERIPROOF_CLIENT_ID" \
--data-urlencode client_secret="$VERIPROOF_CLIENT_SECRET"With an Entra workload identity, send the Entra access token as a client assertion instead of a secret:
curl -s -X POST "$VERIPROOF_API_URL/v1/auth/service-principals/token" \
-d grant_type=client_credentials \
-d client_id="$VERIPROOF_CLIENT_ID" \
-d client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer \
--data-urlencode client_assertion="$ENTRA_ACCESS_TOKEN"The Entra token must be an app-only token issued by the configured tenant to the configured object ID. Unless the deployment sets its own audience, request it for Azure Resource Manager, for example with az account get-access-token --resource https://management.azure.com/.
Send the returned access_token as a bearer token on API requests.
Export a definition
curl -s -H "Authorization: Bearer $TOKEN" \
"$VERIPROOF_API_URL/v1/configuration/applications/$APPLICATION_ID" > refund-assistant.jsonUse /v1/configuration/groups/{groupId} for an application group. Each document names its format, "schema": "veriproof.configuration/v1", so a pipeline can check it before importing.
| An application document includes | A group document includes |
|---|---|
| Field contract | Group field contract |
| Rule definitions, with their source version | Group rule definitions, with their source version |
| Review forms | Group review forms |
| The review route’s reviewer role | The group’s default reviewer role |
| Oversight sampling | Installed policy packs, as provenance |
| Framework scope and group membership | Member applications, for reference |
A document never contains sessions, evidence, decisions, keys, secrets, webhook targets, audit history, or people. Reviewers and coordinators named on a route stay as configured in each application.
Import a definition
Preview the changes with a dry run, then apply:
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
--data-binary @refund-assistant.json \
"$VERIPROOF_API_URL/v1/configuration/applications/$TARGET_APPLICATION_ID/import?dryRun=true"The response lists each section with a status and the changes it would make or made. Importing the same document again makes no changes.
Import applies changes through the same services and permissions as the portal:
- Rules are matched by name and saved as drafts. VeriProof runs a fleet preview for each saved rule and includes the result. Rules missing from the document are left unchanged.
- Active rules are never changed by import. A differing active rule is reported as
needs_person, because saving a change would stop enforcing it until it’s deployed again. - Group membership that would start or stop a group’s active rules on the application is reported as
needs_person. - Production applications follow the production change process. Those changes are reported as
approval_requested. - Policy packs are reported, never installed. A person installs packs in the portal.
To activate a draft, deploy it from the portal or with POST /v1/rules/{id}/deployment. When a service principal requests a deployment, a person must approve it, even if the organization’s change-control profile wouldn’t otherwise require an approval.
Use the CLI
The VeriProof CLI signs in as a service principal when
VERIPROOF_CLIENT_ID and VERIPROOF_CLIENT_SECRET (or VERIPROOF_CLIENT_ASSERTION) are set:
veriproof config export --application "$APPLICATION_ID" --out refund-assistant.json
veriproof policy test --application "$APPLICATION_ID" --definition refund-assistant.json --fail-on-change
veriproof config import refund-assistant.json --dry-runconfig import prints each change and exits with code 1 when a section failed or isn’t
permitted. policy test replays the saved rule tests against the document’s rules before you
import it. See Test rules in CI.
There’s no Terraform provider yet. Use the CLI or the API from your pipeline.