Assign Projects to Governance Policies on the Fly
Enroll each project into the right governance policy straight from your CI/CD pipeline, so every deployment is gated without any manual UI steps.
Overview
This guide is for teams running AI governance at scale — typically one Confident AI project per customer or per agent — that need every project enrolled into a governance policy automatically, without anyone clicking through the platform UI.
It builds directly on Provision Projects for Agents on the Fly: once your pipeline creates a project, the next step is to enroll that project into the governance policy that gates its deployment. A governance policy is organization-scoped (a named bundle of controls), and each project belongs to at most one policy.
In this guide, you will:
- Configure the Admin SDK with one Organization API Key.
- Find the target governance policy by name.
- Assign the project to the policy in code, as part of your pipeline.
- Verify enrollment by reading the project's policy back.
flowchart LR
Pipeline["CI/CD pipeline<br/>(per customer)"]
Pipeline --> Create["Create project"]
Create --> Assign["Assign project to<br/>governance policy"]
Assign --> Gate["Deployment gated<br/>by policy controls"]
classDef pipeline fill:#f8fafc,stroke:#334155,stroke-width:2px,color:#0f172a
classDef step fill:#eef2ff,stroke:#4f46e5,stroke-width:1px,color:#1e293b
class Pipeline pipeline
class Create,Assign,Gate step
Build It
Install the Admin SDK
Governance policies are managed with the
confidentaiAdmin SDK.pip install confidentainpm install confidentaiConfigure the Admin SDK
Set
CONFIDENT_ORG_API_KEYto your Organization API Key. The Admin SDK reads this variable by default when you create a client.export CONFIDENT_ORG_API_KEY="confident_us_org_..."main.py from confidentai import ConfidentAI confident_ai = ConfidentAI()index.ts import { ConfidentAI } from "confidentai"; const confidentAI = new ConfidentAI();Find the Target Policy
Governance policies are created and configured (with their controls) in the platform UI. From code, list them and pick the one your deployment should be gated by — usually by name.
main.py from confidentai import ConfidentAI confident_ai = ConfidentAI() def find_policy_id(policy_name: str) -> str: organization = confident_ai.organization() policies = organization.governance.policies.list() for policy in policies: if policy.name == policy_name: return policy.id raise ValueError(f"No governance policy named {policy_name!r}")index.ts import { ConfidentAI } from "confidentai"; const confidentAI = new ConfidentAI(); async function findPolicyId(policyName: string): Promise<string> { const organization = confidentAI.organization(); const policies = await organization.governance.policies.list(); const policy = policies.find((p) => p.name === policyName); if (!policy) { throw new Error(`No governance policy named ${policyName}`); } return policy.id; }Assign the Project
Assign the project to the policy. Assignment is additive and partial: every project that exists is enrolled and returned in
assignedProjectIds(any on a different policy are moved over), while the policy's other projects are left untouched. Ids that don't exist in your organization come back innotFoundProjectIdsinstead of failing the call — so one stale id never tanks the whole batch. Re-assigning an already-enrolled project still counts it, so this is safe to run on every pipeline execution.main.py from confidentai import ConfidentAI confident_ai = ConfidentAI() # find_policy_id() is defined above def enroll_project(project_id: str, policy_name: str = "Production Gate") -> list[str]: policy_id = find_policy_id(policy_name) organization = confident_ai.organization() result = organization.governance.policies.assign( policy_id, project_ids=[project_id] ) return result.assigned_project_idsindex.ts import { ConfidentAI } from "confidentai"; const confidentAI = new ConfidentAI(); // findPolicyId() is defined above async function enrollProject( projectId: string, policyName = "Production Gate", ): Promise<string[]> { const policyId = await findPolicyId(policyName); const organization = confidentAI.organization(); const result = await organization.governance.policies.assign(policyId, { projectIds: [projectId], }); return result.assignedProjectIds; }Verify Enrollment
Read the project back and confirm it is enrolled. Every project returned by
projects.list()(andproject(id).get()) includes itsgovernancePolicy—{ id, name }when enrolled, ornullwhen not.from confidentai import ConfidentAI confident_ai = ConfidentAI() project = confident_ai.project("project-uuid-1").get() print(project.governance_policy) # NamedRef(id="...", name="Production Gate")import { ConfidentAI } from "confidentai"; const confidentAI = new ConfidentAI(); const project = await confidentAI.project("project-uuid-1").get(); console.log(project.governancePolicy); // { id: "...", name: "Production Gate" }Done! Your pipeline now enrolls each project into the right governance policy using a single Organization API Key.
Gate Deployments in CI
Everything above is the platform team's job — enroll each project into the right policy once, as part of provisioning. From then on, the product team that owns a project gates its own deployments with the deepeval CLI. They don't need the Organization API Key; they only need that project's Project API Key (CONFIDENT_API_KEY).
export CONFIDENT_API_KEY="confident_us_proj_..."
deepeval gateexport CONFIDENT_API_KEY="confident_us_proj_..."
npx deepeval gatedeepeval gate assesses every control in the project's policy and exits with code 0 only when the policy passes — a failure on any control above Low importance exits non-zero and stops the deployment. See Gate Deployments in CI/CD for the full reference.
Next Steps
Provision Projects on the Fly
Create a dedicated project per customer or agent — the step before enrollment.
AI Governance
Configure governance policies and the controls that gate your deployments.
List Governance Policies
See the governance-policy endpoints in the API reference under Organization data models.
Manage Projects
Update and clean up the projects your pipeline creates.
Last updated on