Register assessment graph
Registers an assessment's graph under its agent's root graph, creating the root on the agent's first assessment, and returns the program's control CIDs. Registering the same assessment again is a no-op. Only the Governance Service may call it, with organization-level certify_agents.
post
https://<host>/gov/v1/agent/graphbash
curl --request POST \
--url 'https://<host>/gov/v1/agent/graph' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{"agent":"00000000-0000-0000-0000-000000000000","assessment":"00000000-0000-0000-0000-000000000000","organization":"00000000-0000-0000-0000-000000000000","program":"urn:cid:program_cid"}'javascript
const response = await fetch("https://<host>/gov/v1/agent/graph", {
method: "POST",
headers: {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
},
body: JSON.stringify({
"agent": "00000000-0000-0000-0000-000000000000",
"assessment": "00000000-0000-0000-0000-000000000000",
"organization": "00000000-0000-0000-0000-000000000000",
"program": "urn:cid:program_cid"
})
});
const data = await response.json();typescript
interface AgentGraphResponse {
agent: string;
assessment: string;
controls: Record<string, unknown>;
organization: string;
program: string;
}
const response = await fetch("https://<host>/gov/v1/agent/graph", {
method: "POST",
headers: {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
},
body: JSON.stringify({
"agent": "00000000-0000-0000-0000-000000000000",
"assessment": "00000000-0000-0000-0000-000000000000",
"organization": "00000000-0000-0000-0000-000000000000",
"program": "urn:cid:program_cid"
})
});
if (!response.ok) throw new Error(`${response.status} ${response.statusText}`);
const data: AgentGraphResponse = await response.json();python
import requests
response = requests.post(
"https://<host>/gov/v1/agent/graph",
headers={
"Authorization": "Bearer <token>",
"Content-Type": "application/json",
},
json={
"agent": "00000000-0000-0000-0000-000000000000",
"assessment": "00000000-0000-0000-0000-000000000000",
"organization": "00000000-0000-0000-0000-000000000000",
"program": "urn:cid:program_cid",
},
)
response.raise_for_status()
print(response.json())go
package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"agent": "00000000-0000-0000-0000-000000000000",
"assessment": "00000000-0000-0000-0000-000000000000",
"organization": "00000000-0000-0000-0000-000000000000",
"program": "urn:cid:program_cid"
}`)
req, err := http.NewRequest(http.MethodPost, "https://<host>/gov/v1/agent/graph", 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))
}java
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://<host>/gov/v1/agent/graph"))
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("""
{
"agent": "00000000-0000-0000-0000-000000000000",
"assessment": "00000000-0000-0000-0000-000000000000",
"organization": "00000000-0000-0000-0000-000000000000",
"program": "urn:cid:program_cid"
}
"""))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode() + " " + response.body());
}
}csharp
using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://<host>/gov/v1/agent/graph");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "<token>");
request.Content = new StringContent("""
{
"agent": "00000000-0000-0000-0000-000000000000",
"assessment": "00000000-0000-0000-0000-000000000000",
"organization": "00000000-0000-0000-0000-000000000000",
"program": "urn:cid:program_cid"
}
""", Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");php
<?php
$ch = curl_init('https://<host>/gov/v1/agent/graph');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer <token>',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"agent": "00000000-0000-0000-0000-000000000000",
"assessment": "00000000-0000-0000-0000-000000000000",
"organization": "00000000-0000-0000-0000-000000000000",
"program": "urn:cid:program_cid"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
echo $status . " " . $response . PHP_EOL;ruby
require "net/http"
uri = URI("https://<host>/gov/v1/agent/graph")
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer <token>"
request["Content-Type"] = "application/json"
request.body = <<~'JSON'
{
"agent": "00000000-0000-0000-0000-000000000000",
"assessment": "00000000-0000-0000-0000-000000000000",
"organization": "00000000-0000-0000-0000-000000000000",
"program": "urn:cid:program_cid"
}
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}"rust
// 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()
.post("https://<host>/gov/v1/agent/graph")
.header("Authorization", "Bearer <token>")
.json(&json!({
"agent": "00000000-0000-0000-0000-000000000000",
"assessment": "00000000-0000-0000-0000-000000000000",
"organization": "00000000-0000-0000-0000-000000000000",
"program": "urn:cid:program_cid"
}))
.send()
.await?;
println!("{} {}", response.status(), response.text().await?);
Ok(())
}Authorizations
BearerAuth· HTTP bearer (JWT)
Request bodyrequired
application/json
agentstring<uuid>requiredThe agent's registry UUID, which becomes its root graph's id
assessmentstring<uuid>requiredThe assessment's UUID, which becomes its graph's id
organizationstring<uuid>requiredThe organization that owns the agent
programstringrequiredThe program manifest the assessment is held to, as registered through /gov/v1/cid/program
Examplejson
{
"agent": "00000000-0000-0000-0000-000000000000",
"assessment": "00000000-0000-0000-0000-000000000000",
"organization": "00000000-0000-0000-0000-000000000000",
"program": "urn:cid:program_cid"
}Responses
200The assessment graph, newly registered or as it already was, and the program's control CIDs
application/json
agentstring<uuid>requiredassessmentstring<uuid>requiredcontrolsobjectrequiredControl code -> the CID declarations, submissions and reviews in the assessment cite it by
Show properties
Map of
stringorganizationstring<uuid>requiredprogramstringrequired
Examplejson
{
"agent": "00000000-0000-0000-0000-000000000000",
"assessment": "00000000-0000-0000-0000-000000000000",
"controls": {
"key": "string"
},
"organization": "00000000-0000-0000-0000-000000000000",
"program": "string"
}401Missing or invalid bearer token
application/json
callstackobjectShow properties
object | nullerrorstringrequired
Examplejson
{
"callstack": {},
"error": "string"
}403Caller is not the Governance Service: certify_agents, which no user or API key holds, is required
application/json
callstackobjectShow properties
object | nullerrorstringrequired
Examplejson
{
"callstack": {},
"error": "string"
}409The agent belongs to another organization, the assessment is registered differently, or either id is another graph's
application/json
callstackobjectShow properties
object | nullerrorstringrequired
Examplejson
{
"callstack": {},
"error": "string"
}422The program is not registered, or is not a CID
application/json
callstackobjectShow properties
object | nullerrorstringrequired
Examplejson
{
"callstack": {},
"error": "string"
}500Internal error
application/json
callstackobjectShow properties
object | nullerrorstringrequired
Examplejson
{
"callstack": {},
"error": "string"
}503Auth Service unavailable
application/json
callstackobjectShow properties
object | nullerrorstringrequired
Examplejson
{
"callstack": {},
"error": "string"
}