Governance
Governance policies, solutions, requirements, reviews, evidence and audit.
Access it as client.governance on a Strongly client, or the same path on AsyncStrongly with await. All methods exist on both with identical signatures.
Methods
All methods
add_policy
add_policy(solution_id: str, policy_id: str) -> GovernanceSolution
Apply a published policy to a solution and return the solution.
The policy's required fields and gates become the solution's requirements, and its status is recomputed.
Parameters
solution_id(str): The solution's id.policy_id(str): The id of an active, non-draft policy you can see.
Returns
GovernanceSolution: The solution, with the policy applied.
Raises
ConflictError: The policy is already applied.UnprocessableEntityError: The policy is inactive or a draft.NotFoundError: No solution or no policy you can see has this id.PermissionDeniedError: You may not change the solution.
add_workload
add_workload(solution_id: str, *, type: str, id: str, name: str | None = None) -> GovernanceSolution
Add a workload to a solution and return the solution.
Parameters
solution_id(str): The solution's id.type(str): The workload's resource type key (seeresource_types).id(str): The resource's id, or"*"to govern every resource of the type, including ones created later.name(str | None, optional): Display name; for"*"the API's default is"All <Type> resources".
Returns
GovernanceSolution: The solution, with the workload added.
Raises
ValidationError: An unknown type or an empty id.ConflictError: The workload is already in the solution.NotFoundError: No solution has this id.PermissionDeniedError: You may not change it.
approve_gate_submission
approve_gate_submission(submission_id: str, *, decision: str, comments: str | None = None) -> GateSubmission
Record your decision on a pending approval gate and return the submission.
The gate is satisfied once its quorum approves, and failed on any denial; an administrator's decision settles it (and may overturn an earlier one).
Parameters
submission_id(str): The gate submission's id (seepending_reviews).decision(str):approved,deniedorconditional(recorded with its comments, counting as neither).comments(str | None, optional): Your comments; required when denying.
Returns
GateSubmission: The submission with your decision.
Raises
ValidationError: An unknown decision, or a denial without comments, or the submission is not an approval gate.UnprocessableEntityError: The gate was already decided.NotFoundError: No submission has this id.PermissionDeniedError: You are not one of the gate's reviewers.
audit
audit(*, entity_type: str | None = None, entity_id: str | None = None, solution_id: str | None = None, action: str | None = None, user_id: str | None = None, search: str | None = None, start_date: str | None = None, end_date: str | None = None, sort: str | None = None, limit: int | None = None) -> SyncPaginator[GovernanceAuditEntry]
List the governance audit trail, newest first (platform administrators).
On a multi-tenant platform an organization owner or admin reads their own organization's entries.
Parameters
entity_type(str | None, optional):policy,solution,gate-submissionornotification.entity_id(str | None, optional): Only entries for this entity.solution_id(str | None, optional): Only entries about this solution or its gates.action(str | None, optional): Exact action (created,updated,gate_submitted,gate_approved,gate_waived, ...).user_id(str | None, optional): Only entries by this user.search(str | None, optional): Case-insensitive match on the entity name, entity type or id, action, or user name or id.start_date(str | None, optional): ISO 8601 lower bound on the timestamp.end_date(str | None, optional): ISO 8601 upper bound on the timestamp.sort(str | None, optional): Comma-separated fields,-for descending; the API's default is-timestamp.limit(int | None, optional): The most entries to return;Nonereturns every match.
Returns
SyncPaginator[GovernanceAuditEntry]: The matching entries, fetched a page at a time.
Raises
PermissionDeniedError: The key's user may not read the audit trail.ValidationError:start_dateorend_dateis not an ISO 8601 date.
create_policy
create_policy(*, name: str, description: str, category: str, severity: str, applicable_resource_types: Sequence[str], stages: Sequence[Mapping[str, Any]], is_active: bool, is_draft: bool, tags: Sequence[str] | None = None) -> GovernancePolicy
Create a governance policy (version 1) and return it.
Parameters
name(str): Policy name.description(str): What the policy enforces and why.category(str):Security,Compliance,QualityorOperational.severity(str):Critical,High,Medium,LoworInfo.applicable_resource_types(Sequence[str]): Resource type keys the policy applies to (seeresource_types). Stages may only gate these types.stages(Sequence[Mapping[str, Any]]): Ordered stage definitions, with camelCase keys as the API stores them:{"name", "description", "order", "fields": [...], "gatedResourceTypes": [...], "gate": {...}}`. `orderand gate ids must be unique; a field is{"name", "label", "type", "required", ...}`; a gate is `{"id", "gateKind", "name", "label", "required"}` plus `approvalConfig,thresholdConfig,evidenceConfigorguardrailConfigby kind. An approval gate's reviewers are{"type": "user" | "role" | "group", "identifier", "isActive", "canDelegate"}naming whatreviewer_optionsoffers.is_active(bool): Whether the policy is active.is_draft(bool): Whether the policy is a draft. Only an active, non-draft (published) policy is enforced or can be applied to a solution.tags(Sequence[str] | None, optional): Free-form tags such assoc2; the API stores none when omitted.
Returns
GovernancePolicy: The created policy; you are its creator.
Raises
ValidationError: A required field is missing, an unknown category or severity, or the stages break a rule (a duplicate order or gate id, a gate on a type the policy does not apply to, an approval gate without a reviewer, an unknown reviewer).
create_solution
create_solution(*, name: str, description: str | None = None, workloads: Sequence[Mapping[str, Any]] | None = None, policy_ids: Sequence[str] | None = None) -> GovernanceSolution
Create a solution and return it, its status computed.
Parameters
name(str): Solution name.description(str | None, optional): What the solution covers; the API stores""when omitted.workloads(Sequence[Mapping[str, Any]] | None, optional): Workloads to govern:[{"type": "app", "id": "<id>", "name": "..."}]`, `typea key fromresource_types. Anidof"*"governs every resource of that type, including ones created later.policy_ids(Sequence[str] | None, optional): Ids of published (active, non-draft) policies to apply.
Returns
GovernanceSolution: The created solution; you are its owner.
Raises
ValidationError: An empty name, an unknown workload type or an empty workload id.ConflictError: A workload is listed twice.NotFoundError: A policy you cannot see.UnprocessableEntityError: A policy that is inactive or a draft.
delete_evidence
delete_evidence(evidence_id: str) -> None
Remove an evidence file from its gate.
The gate returns to pending when it holds fewer than its minimum number of files.
Parameters
evidence_id(str): The attachment's id.
Raises
NotFoundError: No evidence file has this id.PermissionDeniedError: You may not change its solution.
delete_policy
delete_policy(policy_id: str) -> None
Delete a policy, with its gate submissions and evidence files.
Parameters
policy_id(str): The policy's id.
Raises
UnprocessableEntityError: A solution still applies the policy (error_coderesource-in-use); remove it from those solutions first.NotFoundError: No policy has this id.PermissionDeniedError: You are not its creator, not shared on it and not an administrator.
delete_solution
delete_solution(solution_id: str) -> None
Delete a solution with its gate submissions and evidence files.
Its workloads stop being governed by it.
Parameters
solution_id(str): The solution's id.
Raises
NotFoundError: No solution has this id.PermissionDeniedError: You may not change it.
download_evidence
download_evidence(evidence_id: str) -> bytes
Download an evidence file.
Parameters
evidence_id(str): The attachment's id (EvidenceAttachment.id).
Returns
bytes: The file's content.
Raises
NotFoundError: No evidence file you can read has this id.
enforcement_check
enforcement_check(*, resource_type: str, resource_id: str, organization_id: str) -> EnforcementResult
Run the go-live governance check for a resource without deploying it.
Parameters
resource_type(str): The resource's type key (seeresource_types).resource_id(str): The resource's id.organization_id(str): The organization the resource belongs to (or will be created in); on a multi-tenant platform its solutions are the ones checked.
Returns
EnforcementResult: Whether the resource may go live, and the requirements that block it, pass or were waived.
Raises
ValidationError: An unknownresource_type.PermissionDeniedError: On a multi-tenant platform, another organization than yours (administrators may check any).
list_policies
list_policies(*, category: str | None = None, severity: str | None = None, is_active: bool | None = None, is_draft: bool | None = None, tag: str | None = None, search: str | None = None, sort: str | None = None, limit: int | None = None) -> SyncPaginator[GovernancePolicy]
List the policies you can see: your own, those shared with you, and every published one.
Parameters
category(str | None, optional):Security,Compliance,QualityorOperational.severity(str | None, optional):Critical,High,Medium,LoworInfo.is_active(bool | None, optional): Only active (True) or only inactive (False) policies.is_draft(bool | None, optional): Only drafts (True) or only non-drafts (False).tag(str | None, optional): Only policies carrying this tag.search(str | None, optional): Case-insensitive match on the name or description.sort(str | None, optional): Comma-separated fields,-for descending; the API's default is-createdAt(newest first).limit(int | None, optional): The most policies to return;Nonereturns every match.
Returns
SyncPaginator[GovernancePolicy]: The matching policies, fetched a page at a time.
list_solutions
list_solutions(*, status: str | None = None, policy_id: str | None = None, workload_type: str | None = None, workload_id: str | None = None, search: str | None = None, sort: str | None = None, limit: int | None = None) -> SyncPaginator[GovernanceSolution]
List the solutions you own or are shared on (an administrator: every one).
Parameters
status(str | None, optional):compliant,non-compliantorin-progress.policy_id(str | None, optional): Only solutions applying this policy.workload_type(str | None, optional): Only solutions with a workload of this type.workload_id(str | None, optional): Withworkload_type, only solutions with exactly this workload ("*"for a type-level binding).search(str | None, optional): Case-insensitive match on the name or description.sort(str | None, optional): Comma-separated fields,-for descending; the API's default is-updatedAt(most recently updated first).limit(int | None, optional): The most solutions to return;Nonereturns every match.
Returns
SyncPaginator[GovernanceSolution]: The matching solutions, fetched a page at a time.
metrics
metrics() -> GovernanceMetrics
Return governance counts over what you can see.
Returns
GovernanceMetrics: Policies (total and published), solutions by status, and approval gates awaiting a decision.
pending_reviews
pending_reviews(*, limit: int | None = None) -> SyncPaginator[GateSubmission]
List the approval gates awaiting a decision that you may decide, newest first.
An administrator sees every one.
Parameters
limit(int | None, optional): The most submissions to return;Nonereturns every one.
Returns
SyncPaginator[GateSubmission]: The pending approval submissions, fetched a page at a time.
policy_versions
policy_versions(policy_id: str) -> PolicyVersionHistory
Return a policy's current version and the versions its changes replaced.
Parameters
policy_id(str): The policy's id.
Returns
PolicyVersionHistory: The current version and, for each earlier one, who replaced it and when.
Raises
NotFoundError: No policy you can see has this id.
recompute_solution
recompute_solution(solution_id: str) -> SolutionStatusSummary
Recompute and save a solution's compliance status.
Parameters
solution_id(str): The solution's id.
Returns
SolutionStatusSummary: The status and the count of requirements in each state.
Raises
NotFoundError: No solution has this id.PermissionDeniedError: You may not change it.
remove_policy
remove_policy(solution_id: str, policy_id: str) -> None
Remove a policy from a solution, with its gate submissions and evidence there.
Parameters
solution_id(str): The solution's id.policy_id(str): The applied policy's id.
Raises
NotFoundError: No solution has this id, or the policy is not applied to it.PermissionDeniedError: You may not change the solution.
remove_workload
remove_workload(solution_id: str, workload_type: str, workload_id: str) -> None
Remove a workload from a solution; it is no longer governed by it.
Parameters
solution_id(str): The solution's id.workload_type(str): The workload's resource type key.workload_id(str): The workload's resource id ("*"for a type-level binding).
Raises
NotFoundError: No solution has this id, or the workload is not in it.PermissionDeniedError: You may not change it.
resource_types
resource_types() -> list[GovernanceResourceType]
List the resource types solutions can govern and stages can gate.
Returns
list[GovernanceResourceType]: The types, with whether single resources of each can be bound.
retrieve_policy
retrieve_policy(policy_id: str) -> GovernancePolicy
Return a policy with its stages, fields and gates.
Parameters
policy_id(str): The policy's id.
Returns
GovernancePolicy: The policy.
Raises
NotFoundError: No policy you can see has this id.
retrieve_solution
retrieve_solution(solution_id: str) -> GovernanceSolution
Return a solution: its workloads, applied policies and compliance status.
Parameters
solution_id(str): The solution's id.
Returns
GovernanceSolution: The solution.
Raises
NotFoundError: No solution has this id.PermissionDeniedError: You do not own it, are not shared on it and are not an administrator.
reviewer_options
reviewer_options() -> ReviewerOptions
Return what an approval gate's reviewer entry can name.
Use the ids as reviewer identifiers: user a user's id,
role a role name, group org:<id> or
org:<id>:role:<owner|admin|member|viewer>. A policy naming any
other reviewer is refused.
Returns
ReviewerOptions: The users you can see, the platform roles, and the organizations (every one for an administrator, otherwise your own).
solution_requirements
solution_requirements(solution_id: str, *, resource_type: str | None = None, limit: int | None = None) -> SyncPaginator[GateRequirement]
List a solution's requirements in stage order, each with its status and submission.
The requirements are the required fields and gates of the published policies the solution applies.
Parameters
solution_id(str): The solution's id.resource_type(str | None, optional): Only the requirements that gate this resource type from going live (whatenforcement_checkevaluates for it).limit(int | None, optional): The most requirements to return;Nonereturns every one.
Returns
SyncPaginator[GateRequirement]: The requirements, fetched a page at a time.
Raises
ValidationError: An unknownresource_type.NotFoundError: No solution you can read has this id.
submit_gate
submit_gate(solution_id: str, gate_id: str, *, policy_id: str, data: Mapping[str, Any] | None = None) -> GateSubmission
Submit one requirement of a solution and return its gate submission.
A submission replaces the requirement's previous one (and any waiver) and the solution's status is recomputed.
Parameters
solution_id(str): The solution's id.gate_id(str): The requirement'sgate_id(seesolution_requirements).policy_id(str): The id of the policy the requirement belongs to.data(Mapping[str, Any] | None, optional): The submitted value, by requirement kind: input{"textValue"},{"numberValue"},{"dateValue"}or{"selectedOptions": [...]}`; acknowledgment `{"acknowledged": True}; approval nothing (requests approval and notifies the reviewers); threshold{"metricValue": 0.93}; guardrail{"guardrailsVerified": True}. Evidence gates take files throughupload_evidence. The API reads a missingdataas{}.
Returns
GateSubmission: The submission; an input that breaks the field's rules isfailedwith afailure_reason.
Raises
ValidationError:datais malformed for the requirement's kind, or the requirement is an evidence gate.UnprocessableEntityError: The policy is inactive or a draft, or approval was already requested or given.NotFoundError: No such solution, policy on it, or requirement.PermissionDeniedError: You may not change the solution.
update_policy
update_policy(policy_id: str, *, name: str | None = None, description: str | None = None, category: str | None = None, severity: str | None = None, applicable_resource_types: Sequence[str] | None = None, stages: Sequence[Mapping[str, Any]] | None = None, is_active: bool | None = None, is_draft: bool | None = None, tags: Sequence[str] | None = None) -> GovernancePolicy
Change a policy and return it; only the fields given change.
A change to the stages, severity or applicable resource types adds a
version (see policy_versions), and every solution applying the
policy has its status recomputed.
Parameters
policy_id(str): The policy's id.name(str | None, optional): New name.description(str | None, optional): New description.category(str | None, optional):Security,Compliance,QualityorOperational.severity(str | None, optional):Critical,High,Medium,LoworInfo.applicable_resource_types(Sequence[str] | None, optional): New applicable resource types.stages(Sequence[Mapping[str, Any]] | None, optional): The whole new stage list (shape as increate_policy); the stagesretrieve_policyreturns can be edited and sent back.is_active(bool | None, optional): Whether the policy is active.is_draft(bool | None, optional): Whether the policy is a draft.tags(Sequence[str] | None, optional): The whole new tag list.
Returns
GovernancePolicy: The updated policy.
Raises
ValidationError: No field is given, or a field or the resulting stages are invalid.NotFoundError: No policy has this id.PermissionDeniedError: You are not its creator, not shared on it and not an administrator.
update_solution
update_solution(solution_id: str, *, name: str | None = None, description: str | None = None) -> GovernanceSolution
Rename a solution or change its description, and return it.
Use add_workload and add_policy to change what it
governs.
Parameters
solution_id(str): The solution's id.name(str | None, optional): New name.description(str | None, optional): New description.
Returns
GovernanceSolution: The updated solution.
Raises
ValidationError: Neither field is given, or the name is empty.NotFoundError: No solution has this id.PermissionDeniedError: You may not change it.
upload_evidence
upload_evidence(solution_id: str, gate_id: str, *, policy_id: str, file: FileInput) -> EvidenceAttachment
Upload one evidence file to an evidence gate and return the attachment.
The gate is satisfied once it holds its minimum number of files.
Parameters
solution_id(str): The solution's id.gate_id(str): The evidence gate's id.policy_id(str): The id of the policy the gate belongs to.file(str | Path | BinaryIO): A path or a binary file object; its name's extension must be one of the gate's allowed file types.
Returns
EvidenceAttachment: The stored file, with the iddownload_evidencetakes.
Raises
FileNotFoundError:fileis a path that does not exist.ValidationError: An empty file, or a file type the gate does not allow, or the gate is not an evidence gate.PayloadTooLargeError: The file is larger than the gate allows.UnprocessableEntityError: The policy is inactive or a draft.NotFoundError: No such solution, policy on it, or gate.PermissionDeniedError: You may not change the solution.
waive_gate_submission
waive_gate_submission(submission_id: str, *, reason: str) -> GateSubmission
Waive a submitted requirement with a written reason (platform administrators).
A waived requirement counts as satisfied until it is submitted again.
Parameters
submission_id(str): The gate submission's id (the requirement must have been submitted at least once).reason(str): The justification recorded with the waiver.
Returns
GateSubmission: The waived submission.
Raises
ValidationError:reasonis empty.UnprocessableEntityError: The requirement is already waived.NotFoundError: No submission has this id.PermissionDeniedError: The key's user is not a platform administrator.