Skip to main content
Version: 1.60

Controls & Frameworks

Controls are policy checks that can be attached to deployments to enforce governance requirements across their lifecycle. A control framework groups a set of controls and applies them to one or more workspaces.

This guide walks through the full workflow:

  1. Define controls in a CSV file
  2. Convert the CSV to JSON
  3. Create controls via the API
  4. Bundle them into a control framework

CSV format

Controls are defined in a CSV file with the following columns. Column order does not matter; names must match exactly.

ColumnRequiredDescription
idShort identifier / abbreviation (e.g. CT1, CTRL-001)
nameHuman-readable name
stageLifecycle stage: exploration, development, validation, or production
descriptionDetailed description (truncated to 500 characters if longer)
categoryGrouping category (free text)
riskClassificationsComma-separated risk classification tags, or all to target all classifications (see Risk classifications)
checksSemicolon-separated check definitions (see Checks)

Example CSV

id,category,stage,name,description,riskClassifications,checks
CT1,Compliance,exploration,Data Privacy Control,Ensure data privacy compliance requirements are met,,
CT2,Governance,development,Model Documentation,Document all model decisions and rationale,all,"type:13, selectedOption:Instructions for use"
CT3,Security,production,Access Control,Implement role-based access control,"high,limited","type:21, matchCondition:includes, selectedOption:Quality Management System; type:8, selectedOption:response time"
CT4,Compliance,validation,Bias Testing,Test for model bias and fairness,limited,"type:7, percentage:80, timeframe:7 days"
CT5,Governance,production,Alert Monitoring,Monitor critical metrics,,"type:7, percentage:80, timeframe:7 days"
CT6,Technical,development,Predictions Made,Ensure minimum prediction volume,high,"type:3, count:50, timeframe:172800000"
CT7,Compliance,validation,Documentation Upload,Required documentation must be present,,"type:21, matchCondition:startsWith, selectedOption:Project Plan"

Risk classifications

ValueMeaning
all or leave emptyApplies to all risk classifications (stored as an empty list)
unacceptableUnacceptable risk
highHigh risk
limitedLimited risk
minimalMinimal risk
generalPurposeAIGeneral Purpose AI

Multiple values are comma-separated: high,limited. Unknown values are silently dropped with a warning.

Checks

A check is expressed as a comma-separated list of key:value pairs. The type key is always required and refers to the type ID from the table below. Multiple checks on a single control are separated by ;.

type:3, count:50, timeframe:7 days
type:21, matchCondition:includes, selectedOption:Quality Management System; type:8, selectedOption:response time

Timeframe can be written as a human-friendly string (7 days, 1 day) or as an integer number of milliseconds (604800000).

Available check types

Type IDCodeNameParameters
0PRIVATE_REPOSITORYLinked repository is private
1PRIVATE_OBJECTArtifact stored privatelyselectedOption: model | explainer | transformer
2DEPLOYMENT_UPDATEDDeployment regularly updatedtimeframe
3PREDICTIONS_MADEDeployment Activitycount, timeframe
4EXPLAINER_DEPLOYEDExplainer deployed
5PREDICTIONS_EXPLAINEDPredictions explainedpercentage, timeframe
6PREDICTIONS_EVALUATEDEvaluations submittedpercentage, timeframe
7PREDICTIONS_HAVE_ACTUALSActuals submittedpercentage, timeframe
8ALERT_RULE_SETAlert rule addedselectedOption: metric name (e.g. accuracy, response time, feature drift)
9DESCRIPTION_AVAILABLEDescription available
10MODEL_CARD_AVAILABLEModel card available
11METADATA_FIELD_SPECIFIEDMetadata field specifiedselectedOption: customId | exampleInput | features | …
12DATA_CARD_AVAILABLEData card available
13DOCUMENTATION_TEMPLATE_COMPLETEDDocumentation template completedselectedOption: template name (free text)
14EVENTS_TRACKEDEvents are logged
15VERSIONS_TRACKEDVersion control maintained
16ALERT_RULE_FOR_PERFORMANCE_SETAlert rule for performance added
17USE_CASE_HAS_RISK_CLASSIFICATIONRisk classification assigned
18USE_CASE_RISK_ASSESSMENT_COMPLETEDRisk classification assessment completed
19LIFE_CYCLE_STAGES_INCORPORATEDLifecycle stages incorporated
20ALERT_RULE_FOR_DRIFT_SETAlert rule for drift added
21DOCUMENTATION_UPLOADEDDocumentation uploadedmatchCondition: equals | includes | endsWith | startsWith, selectedOption: document name (free text)
22GUARDRAILS_ENABLEDGuardrail appliedselectedOption: input | output
23PERIODIC_REVIEWPeriodic review

Converting the CSV

The CSV must be converted to a JSON file before uploading to Deeploy. Rows with an invalid stage value are skipped with a warning; all other fields that cannot be parsed are also skipped or defaulted.

Using the CLI

deeploy convert-controls path/to/controls.csv

By default the output is written to <csv_stem>_controls.json next to the input file. Use --output / -o to choose a different destination:

deeploy convert-controls path/to/controls.csv -o path/to/controls.json

Using Python

from deeploy.common.functions.controls_converter import csv_to_controls_json

# Writes controls.json and returns the output path
output_path = csv_to_controls_json("path/to/controls.csv", "path/to/controls.json")
print(f"Written to: {output_path}")

Output format

The resulting JSON is a list of objects, each wrapping a single control:

[
{
"control": {
"abbreviation": "CT3",
"name": "Access Control",
"stage": "production",
"description": "Implement role-based access control",
"category": "Security",
"riskClassifications": ["high", "limited"],
"checks": [
{
"type": 21,
"matchCondition": "includes",
"selectedOption": "Quality Management System"
},
{
"type": 8,
"selectedOption": "response time"
}
]
}
}
]

Creating controls

Pass the loaded JSON list directly to client.create_controls(). The method accepts both the {"control": {...}} wrapper format produced by the converter and plain dicts or CreateControl instances.

import json
from deeploy import Client
from deeploy.common.functions.controls_converter import csv_to_controls_json

# 1. Convert the CSV to JSON
csv_to_controls_json("controls.csv", "controls.json")

# 2. Load the JSON
with open("controls.json") as f:
controls_data = json.load(f)

# 3. Initialise the client
client = Client(
host="<your-host>",
access_key="<your-access-key>",
secret_key="<your-secret-key>",
)

# 4. Create the controls
created = client.create_controls(controls_data)
print(f"Created {len(created)} controls")

create_controls returns a list of Control objects. Each object has an id field that is needed when building a framework.

note

create_controls does not require a workspace_id on the client because controls are organization-level resources, not workspace-scoped.

Creating a control framework

A framework groups controls and optionally assigns them to specific workspaces.

framework = client.create_control_framework({
"name": "My Governance Framework",
"description": "Core controls for all production deployments",
"control_ids": [c.id for c in created],
"workspace_ids": [], # empty list = not yet assigned to any workspace
})

print(f"Framework created: {framework.id}")

End-to-end example

import json
from deeploy import Client
from deeploy.common.functions.controls_converter import csv_to_controls_json

# Convert CSV → JSON
csv_to_controls_json("controls.csv", "controls.json")
with open("controls.json") as f:
controls_data = json.load(f)

# Create client
client = Client(
host="<your-host>",
access_key="<your-access-key>",
secret_key="<your-secret-key>",
)

# Create controls
created = client.create_controls(controls_data)

# Bundle into a framework
framework = client.create_control_framework({
"name": "My Governance Framework",
"description": "Core controls for all production deployments",
"control_ids": [c.id for c in created],
"workspace_ids": [],
})

print(f"Framework '{framework.name}' created with {len(framework.controls)} controls")