EQTY LabDocs

Compute agent profile CID

Computes the JCS CID of an agent operating profile and stores it in the blob store. Returns the CID an assessment pins and its certification names. A profile is its owner's declaration of how an agent operates, saved as a version on the agent in control-plane; governance checks that the CID returned here equals the one control-plane computed. The document names no agent, so every agent of one design shares its CID. Only governance registers a profile, as its governance-worker service account, once it has checked the version belongs to the assessed agent. The profile is recorded as one, so an assessment can pin it and nothing else.

posthttps://<host>/gov/v1/cid/agent-profile
bash
curl --request POST \
  --url 'https://<host>/gov/v1/cid/agent-profile' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{}'
javascript
const response = await fetch("https://<host>/gov/v1/cid/agent-profile", {
  method: "POST",
  headers: {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({})
});

const data = await response.json();
typescript
interface CidAgentProfileResponse {
  profile: string;
}

const response = await fetch("https://<host>/gov/v1/cid/agent-profile", {
  method: "POST",
  headers: {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({})
});
if (!response.ok) throw new Error(`${response.status} ${response.statusText}`);

const data: CidAgentProfileResponse = await response.json();
python
import requests

response = requests.post(
    "https://<host>/gov/v1/cid/agent-profile",
    headers={
        "Authorization": "Bearer <token>",
        "Content-Type": "application/json",
    },
    json={},
)
response.raise_for_status()
print(response.json())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{}`)
	req, err := http.NewRequest(http.MethodPost, "https://<host>/gov/v1/cid/agent-profile", 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/cid/agent-profile"))
            .header("Authorization", "Bearer <token>")
            .header("Content-Type", "application/json")
            .method("POST", HttpRequest.BodyPublishers.ofString("""
                {}
                """))
            .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/cid/agent-profile");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "<token>");
request.Content = new StringContent("""
    {}
    """, 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/cid/agent-profile');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer <token>',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => <<<'JSON'
    {}
    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/cid/agent-profile")
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer <token>"
request["Content-Type"] = "application/json"
request.body = <<~'JSON'
  {}
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/cid/agent-profile")
        .header("Authorization", "Bearer <token>")
        .json(&json!({}))
        .send()
        .await?;

    println!("{} {}", response.status(), response.text().await?);
    Ok(())
}

Authorizations

  • BearerAuth · HTTP bearer (JWT)

Request bodyrequired

An AgentOperatingProfileV1 document, as libs/guardian/agent-profile's JSON Schema describes it

application/json

object

Responses

200The CID of the operating profile

application/json
  • profilestringrequired
Examplejson
{
  "profile": "string"
}

400The document's type or schemaVersion names a profile type or schema version other than AgentOperatingProfileV1 schema 1

application/json
  • callstackobject
    Show properties

    object | null

  • errorstringrequired
Examplejson
{
  "callstack": {},
  "error": "string"
}

401Missing or invalid bearer token

application/json
  • callstackobject
    Show properties

    object | null

  • errorstringrequired
Examplejson
{
  "callstack": {},
  "error": "string"
}

403Caller is not the Governance Service: certify_agents, which no user or API key holds, is required

application/json
  • callstackobject
    Show properties

    object | null

  • errorstringrequired
Examplejson
{
  "callstack": {},
  "error": "string"
}

422The document breaks a profile rule, named by its JSON path: a missing or non-string type or schemaVersion, an unknown or missing field, a value outside a vocabulary, a malformed match rule, an unsorted list, an embedded credential or a size limit

application/json
  • callstackobject
    Show properties

    object | null

  • errorstringrequired
Examplejson
{
  "callstack": {},
  "error": "string"
}

500Internal error recording the profile

application/json
  • callstackobject
    Show properties

    object | null

  • errorstringrequired
Examplejson
{
  "callstack": {},
  "error": "string"
}

503Auth Service or blob storage unavailable

application/json
  • callstackobject
    Show properties

    object | null

  • errorstringrequired
Examplejson
{
  "callstack": {},
  "error": "string"
}