Revoke an agent certification
Revoke one of an assessment's certifications, as an applied policy credential is revoked: with the Integrity Service on the caller's token, then confirmed against the credential's status before it is recorded, so a failed revocation is never recorded. The caller administers programs, or is the reviewer who authorized the certification, as a project's auditor revokes its compliance credential; each certification's canRevoke says which. That reviewer reads the assessment while they still review its program, so one removed since gets 404, and governance vouches for their revocation to the Integrity Service with its own service token, which that service requires of anyone who does not administer programs. Revocation is final; certifying the agent again takes a new submission. Once it is recorded, a gateway that holds the certification reads its status again on the caller's token, so it stops honoring it at once rather than at its next refresh; gateway says how that went, not_attached when the gateway never held it, and a failure there undoes nothing. The caller acts in person, or through their API key bound to no project with full access, or with the manage_programs scope to revoke as an administrator or the review_agent_assessments scope to revoke as the reviewer who authorized it
https://localhost:10001/api/v1/organizations/{orgId}/assessments/{assessmentId}/certifications/{credentialId}/revokecurl --request PUT \
--url 'https://localhost:10001/api/v1/organizations/{orgId}/assessments/{assessmentId}/certifications/{credentialId}/revoke' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{"reason":"string"}'const response = await fetch("https://localhost:10001/api/v1/organizations/{orgId}/assessments/{assessmentId}/certifications/{credentialId}/revoke", {
method: "PUT",
headers: {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
},
body: JSON.stringify({
"reason": "string"
})
});
const data = await response.json();interface CertificationResponse {
agentName?: string;
agentUrn?: string;
assessmentUuid?: string;
canRevoke?: boolean;
configurationCid?: string;
credential?: Record<string, unknown>;
credentialId?: string;
expiresAt?: string;
gateway?: Record<string, unknown>;
issuedAt?: string;
issuedBy?: string;
issuedByDid?: string;
issuedByUserId?: string;
profileCid?: string;
programManifestCid?: string;
programSlug?: string;
programUuid?: string;
provenance?: Record<string, unknown>;
revoked?: boolean;
revokedAt?: string;
revokedBy?: string;
revokedByDid?: string;
revokedByUserId?: string;
revokedReason?: string;
sourceCid?: string;
status?: "active" | "expired" | "revoked";
submissionNumber?: number;
}
const response = await fetch("https://localhost:10001/api/v1/organizations/{orgId}/assessments/{assessmentId}/certifications/{credentialId}/revoke", {
method: "PUT",
headers: {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
},
body: JSON.stringify({
"reason": "string"
})
});
if (!response.ok) throw new Error(`${response.status} ${response.statusText}`);
const data: CertificationResponse = await response.json();import requests
response = requests.put(
"https://localhost:10001/api/v1/organizations/{orgId}/assessments/{assessmentId}/certifications/{credentialId}/revoke",
headers={
"Authorization": "Bearer <token>",
"Content-Type": "application/json",
},
json={
"reason": "string",
},
)
response.raise_for_status()
print(response.json())package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"reason": "string"
}`)
req, err := http.NewRequest(http.MethodPut, "https://localhost:10001/api/v1/organizations/{orgId}/assessments/{assessmentId}/certifications/{credentialId}/revoke", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
fmt.Println(res.Status, string(data))
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://localhost:10001/api/v1/organizations/{orgId}/assessments/{assessmentId}/certifications/{credentialId}/revoke"))
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.method("PUT", HttpRequest.BodyPublishers.ofString("""
{
"reason": "string"
}
"""))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode() + " " + response.body());
}
}using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Put, "https://localhost:10001/api/v1/organizations/{orgId}/assessments/{assessmentId}/certifications/{credentialId}/revoke");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "<token>");
request.Content = new StringContent("""
{
"reason": "string"
}
""", Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");<?php
$ch = curl_init('https://localhost:10001/api/v1/organizations/{orgId}/assessments/{assessmentId}/certifications/{credentialId}/revoke');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer <token>',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"reason": "string"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
echo $status . " " . $response . PHP_EOL;require "net/http"
uri = URI("https://localhost:10001/api/v1/organizations/{orgId}/assessments/{assessmentId}/certifications/{credentialId}/revoke")
request = Net::HTTP::Put.new(uri)
request["Authorization"] = "Bearer <token>"
request["Content-Type"] = "application/json"
request.body = <<~'JSON'
{
"reason": "string"
}
JSON
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
http.request(request)
end
puts "#{response.code} #{response.body}"// Cargo.toml dependencies: reqwest (features "json"), serde_json, tokio (features "full")
use serde_json::json;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let response = reqwest::Client::new()
.put("https://localhost:10001/api/v1/organizations/{orgId}/assessments/{assessmentId}/certifications/{credentialId}/revoke")
.header("Authorization", "Bearer <token>")
.json(&json!({
"reason": "string"
}))
.send()
.await?;
println!("{} {}", response.status(), response.text().await?);
Ok(())
}Authorizations
BearerAuth· API key in header "Authorization" — Type "Bearer" followed by a space and JWT token.
Parameters
Path parameters
| Name | Type | Description |
|---|---|---|
orgIdrequired | string | Organization ID or UUID (urn:uuid optional) |
assessmentIdrequired | string | Assessment UUID (urn:uuid optional) |
credentialIdrequired | string | The certification's credential UUID (urn:uuid optional) |
Request bodyrequired
Revocation reason
reasonstringrequired
{
"reason": "string"
}Responses
200Revoked certification, with what refreshing the gateway's copy did
agentNamestringread-onlyThe agent's display name in the agent registry when its assessment last read it; a label only, never part of the credential
agentUrnstringread-onlyThe credential's subject: the agent's registry ID
assessmentUuidstringread-onlyurn:uuid form
canRevokebooleanread-onlyWhether the caller may revoke it: it is not revoked, and they administer programs or are the reviewer who authorized it and still review its program; false for an API key that does not act as its holder
configurationCidstringread-onlyThe configuration it certifies, pinned by the submission
credentialobjectread-onlyThe signed credential, as issued
credentialIdstringread-onlyThe credential's urn:uuid, which identifies the certification
expiresAtstring<date-time>read-onlyThe credential's validUntil; absent when the program sets no term
gatewayobjectIssuing attaches the certification to the gateway, and revoking has the gateway read its status again; either way a failure there undoes nothing
Show properties
configurationStatusstring (enum)How the agent's keys stand against the configuration it certifies, each by its newest request: current (every key seen lately runs it), partly_drifted (some do; the gateway refuses the rest), drifted (none do) or idle (no key seen lately). Set when attached or refreshed and valid: a certification the gateway won't honor has no keys standing against it
One of
currentpartly_drifteddriftedidlecurrentbooleanWhether the gateway enforces the agent's program from it. Set when attached or refreshed
errorstringWhen failed: why, and what to do
errorCodestringWhen failed: the gateway's error code, or control_plane_unavailable when it could not be reached
operatingProfileStatusstring (enum)Whether the agent still holds the operating profile it certifies. Set when attached or refreshed
One of
matchmismatchunknownoutcomestring (enum)attached or refreshed: the gateway holds it, as validationStatus says; not_attached: it never held this revoked certification; failed: it could not be updated, as error says
One of
attachedrefreshednot_attachedfailedvalidationStatusstring (enum)The gateway's verification of it; it honors only a valid one. Set when attached or refreshed
One of
validexpirednot_yet_validrevokedinvaliduntrusted_issuer
issuedAtstring<date-time>read-onlyissuedBystringread-onlyThe program administrator who requested it
issuedByDidstringread-onlyVerifiable actor, the credential's authorizedBy; issuedBy is the label
issuedByUserIdstringread-onlyprofileCidstringread-onlyThe operating profile it certifies the agent against, pinned by the submission; absent when none was
programManifestCidstringread-onlyThe program version it certifies against
programSlugstringread-onlyThe program the version belongs to
programUuidstringread-onlyurn:uuid form
provenanceobjectread-onlyWho certified what: the statements the credential's evidence names, read back from the submission it certifies. Only for a caller who may read its assessment: absent for one who only sees the agent, and for a key scoped to view_agent_certifications
Show properties
declarationscore.CertificationDeclaration[]The declarations its evidence names, in the evidence's order
Show properties
Array of
core.CertificationDeclarationcontrolsstring[]The control codes it covers, in the program's order
documentCidstringurn:cid of the declaration document
statementIdstringurn:cid of the governance statement it registered as
submittedAtstring<date-time>submittedBystringsubmittedByDidstringsubmittedByUserIdstringuuidstringurn:uuid form
reviewscore.ControlReview[]The review of each control it rests on, in the evidence's order, which is the program's
Show properties
Array of
core.ControlReviewcontrolCodestringdocumentCidstringurn:cid of the review document the Integrity Service stored
evidenceCidstringurn:cid of the control's evidence the review judged; absent on reviews made before controls carried evidence
outcomeobjectOne of
satisfiednot_satisfiednot_applicableShow properties
object (enum)· one of satisfied, not_satisfied, not_applicablereviewedAtstring<date-time>reviewedBystringreviewedByDidstringreviewedByUserIdstringstatementstringstatementIdstringurn:cid of the governance statement it registered as
uuidstringread-onlyurn:uuid form
submissionobjectThe submission it certifies
Show properties
documentCidstringurn:cid of the submission document
numberintegerstatementIdstringurn:cid of the governance statement it registered as
submittedAtstring<date-time>submittedBystringsubmittedByDidstringsubmittedByUserIdstringuuidstringurn:uuid form
unmatchedstring[]Statements its evidence names that are none of these, by urn:cid; never expected, and never hidden
revokedbooleanread-onlySet via the revoke endpoint
revokedAtstring<date-time>read-onlySet via the revoke endpoint
revokedBystringread-onlySet via the revoke endpoint
revokedByDidstringread-onlyVerifiable actor; revokedBy is the label
revokedByUserIdstringread-onlySet via the revoke endpoint
revokedReasonstringread-onlySet via the revoke endpoint
sourceCidstringread-onlyWhere the Integrity Service stored the signed credential
statusobjectread-onlyComputed on read: revoked, else expired once expiresAt passes, else active
One of
activeexpiredrevokedShow properties
object (enum)— Computed on read: revoked, else expired once expiresAt passes, else active · one of active, expired, revokedsubmissionNumberintegerread-onlyThe submission it certifies
{
"agentName": "string",
"agentUrn": "string",
"assessmentUuid": "string",
"canRevoke": true,
"configurationCid": "string",
"credential": {},
"credentialId": "string",
"expiresAt": "2025-01-01T00:00:00Z",
"gateway": {
"configurationStatus": "current",
"current": true,
"error": "string",
"errorCode": "string",
"operatingProfileStatus": "match",
"outcome": "attached",
"validationStatus": "valid"
},
"issuedAt": "2025-01-01T00:00:00Z",
"issuedBy": "string",
"issuedByDid": "string",
"issuedByUserId": "string",
"profileCid": "string",
"programManifestCid": "string",
"programSlug": "string",
"programUuid": "string",
"provenance": {
"declarations": [
{
"controls": [
"string"
],
"documentCid": "string",
"statementId": "string",
"submittedAt": "2025-01-01T00:00:00Z",
"submittedBy": "string",
"submittedByDid": "string",
"submittedByUserId": "string",
"uuid": "string"
}
],
"reviews": [
{
"controlCode": "string",
"documentCid": "string",
"evidenceCid": "string",
"outcome": "satisfied",
"reviewedAt": "2025-01-01T00:00:00Z",
"reviewedBy": "string",
"reviewedByDid": "string",
"reviewedByUserId": "string",
"statement": "string",
"statementId": "string"
}
],
"submission": {
"documentCid": "string",
"number": 0,
"statementId": "string",
"submittedAt": "2025-01-01T00:00:00Z",
"submittedBy": "string",
"submittedByDid": "string",
"submittedByUserId": "string",
"uuid": "string"
},
"unmatched": [
"string"
]
},
"revoked": true,
"revokedAt": "2025-01-01T00:00:00Z",
"revokedBy": "string",
"revokedByDid": "string",
"revokedByUserId": "string",
"revokedReason": "string",
"sourceCid": "string",
"status": "active",
"submissionNumber": 0
}400Bad request - Invalid IDs, missing reason, or the certification carries no revocation status
errorstring
{
"error": "Invalid request body"
}401Unauthorized - Authentication required
errorstring
{
"error": "Invalid request body"
}403Forbidden - Neither administers programs nor authorized the certification, an API key with neither full access nor the scope of either, a project-bound key, or the Integrity Service refuses the caller
errorstring
{
"error": "Invalid request body"
}404Assessment or certification not found, or not readable by the caller
errorstring
{
"error": "Invalid request body"
}409The certification was revoked already
errorstring
{
"error": "Invalid request body"
}500Internal server error
errorstring
{
"error": "Invalid request body"
}