EQTY LabDocs

List the states of a custom agent's definition

Lists the states the agent's requests carried that named definition_cid within the window the days parameter sets (default 30 days, at most 90), newest first: one row per state however many requests carried it, with the sub-agent it was recorded for ("" for the agent itself), the keys that presented it (revoked ones included), the configurations it gave, when it was first and last seen, and how many requests carried it. A request whose state the gateway couldn't read at the time is recorded with no definition, so it isn't counted in requests or the seen-at times, which can be lower than state-cids shows. Viper signs a new state for an unchanged definition on every restart and every few minutes, so these are mostly re-signings. A definition_cid that isn't an agent definition's content ID is a 400, and an unknown one lists none. Readable by an admin and by users bound to the agent.

gethttps://<host>/api/v1/agents/{agentId}/definitions/{definitionCid}/states
bash
curl --request GET \
  --url 'https://<host>/api/v1/agents/{agentId}/definitions/{definitionCid}/states' \
  --header 'Authorization: Bearer <token>'
javascript
const response = await fetch("https://<host>/api/v1/agents/{agentId}/definitions/{definitionCid}/states", {
  method: "GET",
  headers: {
    "Authorization": "Bearer <token>"
  }
});

const data = await response.json();
typescript
interface AgentDefinitionStateListResponse {
  agent_id?: string;
  correlation_id?: string;
  definition_cid?: string;
  items?: Record<string, unknown>[];
}

const response = await fetch("https://<host>/api/v1/agents/{agentId}/definitions/{definitionCid}/states", {
  method: "GET",
  headers: {
    "Authorization": "Bearer <token>"
  }
});
if (!response.ok) throw new Error(`${response.status} ${response.statusText}`);

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

response = requests.get(
    "https://<host>/api/v1/agents/{agentId}/definitions/{definitionCid}/states",
    headers={
        "Authorization": "Bearer <token>",
    },
)
response.raise_for_status()
print(response.json())
go
package main

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

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://<host>/api/v1/agents/{agentId}/definitions/{definitionCid}/states", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer <token>")

	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>/api/v1/agents/{agentId}/definitions/{definitionCid}/states"))
            .header("Authorization", "Bearer <token>")
            .method("GET", HttpRequest.BodyPublishers.noBody())
            .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 var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://<host>/api/v1/agents/{agentId}/definitions/{definitionCid}/states");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "<token>");

using var response = await client.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");
php
<?php

$ch = curl_init('https://<host>/api/v1/agents/{agentId}/definitions/{definitionCid}/states');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer <token>',
    ],
    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>/api/v1/agents/{agentId}/definitions/{definitionCid}/states")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer <token>"

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, tokio (features "full")

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let response = reqwest::Client::new()
        .get("https://<host>/api/v1/agents/{agentId}/definitions/{definitionCid}/states")
        .header("Authorization", "Bearer <token>")
        .send()
        .await?;

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

Authorizations

  • BearerAuth · API key in header "Authorization" — Type "Bearer" followed by a space and a sign-in token: a Guardian Platform JWT, or an OIDC ID token in a standalone deployment.
  • ApiKeyAuth · API key in header "Authorization" — Type "Bearer" followed by a space and a Guardian Platform API key. Project-scoped routes and registration tokens check the key's scopes and project binding. Per-agent routes accept a key bound to no project that has empty scopes or full access, which acts as its holder, or a scope for what the route does: submit_agent_assessments reads an agent (its detail, configurations, state history and the files a state references, definitions, tools and operating profile, as its assessments rest on), view_agent_certifications reads its certifications, and manage_programs or review_agent_assessments attach a certification. A state's raw snapshot and findings, its audit exchanges and plugin events, and saving its operating profile take full access. A scope counts only while the key's holder still holds that permission in the key's organization, which auth-service reports as keyHeldScopes. A key never acts as an admin, so its holder's binding to the agent still decides.

Parameters

Path parameters

NameTypeDescription
agentId
required
string

Agent ID

definitionCid
required
string

Definition CID, from the agent's definitions

Query parameters

NameTypeDescription
daysinteger

How many days back to look (default 30, max 90)

limitinteger

Most states to list (default 25, max 100)

Responses

200OK

application/json
  • agent_idstring
  • correlation_idstring
  • definition_cidstring
  • itemsgithub_com_eqtylab_gateway_control-plane_service_internal_discovery.AgentDefinitionState[]
    Show properties

    Array of github_com_eqtylab_gateway_control-plane_service_internal_discovery.AgentDefinitionState

    • configuration_cidsstring[]
    • first_seen_atstring
    • key_didsstring[]
    • last_seen_atstring
    • requestsinteger
    • state_cidstring
    • sub_agentstring
Examplejson
{
  "agent_id": "string",
  "correlation_id": "string",
  "definition_cid": "string",
  "items": [
    {
      "configuration_cids": [
        "string"
      ],
      "first_seen_at": "string",
      "key_dids": [
        "string"
      ],
      "last_seen_at": "string",
      "requests": 0,
      "state_cid": "string",
      "sub_agent": "string"
    }
  ]
}

400Bad Request

application/json
  • codestring
  • correlation_idstring
  • messagestring
Examplejson
{
  "code": "string",
  "correlation_id": "string",
  "message": "string"
}

401Unauthorized

application/json
  • codestring
  • correlation_idstring
  • messagestring
Examplejson
{
  "code": "string",
  "correlation_id": "string",
  "message": "string"
}

403Forbidden

application/json
  • codestring
  • correlation_idstring
  • messagestring
Examplejson
{
  "code": "string",
  "correlation_id": "string",
  "message": "string"
}

404Not Found

application/json
  • codestring
  • correlation_idstring
  • messagestring
Examplejson
{
  "code": "string",
  "correlation_id": "string",
  "message": "string"
}

500Internal Server Error

application/json
  • codestring
  • correlation_idstring
  • messagestring
Examplejson
{
  "code": "string",
  "correlation_id": "string",
  "message": "string"
}