curl --request GET \
--url https://audit.basaltic.sh/v1/audit-logs \
--header 'Authorization: Bearer <token>'import requests
url = "https://audit.basaltic.sh/v1/audit-logs"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://audit.basaltic.sh/v1/audit-logs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://audit.basaltic.sh/v1/audit-logs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://audit.basaltic.sh/v1/audit-logs"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://audit.basaltic.sh/v1/audit-logs")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://audit.basaltic.sh/v1/audit-logs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"audit_logs": [
{
"crn": "crn:audit:::log/550e8400-e29b-41d4-a716-446655440000",
"id": "e5f6a7b8-c9d0-1234-5678-90abcdef1234",
"timestamp": "2026-01-15T09:30:00Z",
"actor_crn": "crn:workspace:::organization/7c9e6679-7425-40de-944b-e07fc1f90ae7/user/550e8400-e29b-41d4-a716-446655440000",
"resource_crn": "crn:workspace:::organization/550e8400-e29b-41d4-a716-446655440000",
"actor_name": "John Doe",
"actor_email": "john.doe@acme.com",
"action": "iam.policy.create",
"status": "success",
"resource_name": "web-server-1",
"ip_address": "192.168.1.100",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
"request_id": "req-7c9e6679742540de",
"details": {},
"error_code": "access_denied",
"error_message": "Principal is not authorized to perform this action"
}
],
"meta": {
"total": 150,
"limit": 20,
"marker": "550e8400-e29b-41d4-a716-446655440000",
"has_more": true
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "ACCESS_DENIED",
"message": "You don't have permission to perform this action",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}Listar registros de auditoría
Enumera los registros de auditoría de la organización actual con filtrado y paginación. Requiere permiso audit:ListLogs.
curl --request GET \
--url https://audit.basaltic.sh/v1/audit-logs \
--header 'Authorization: Bearer <token>'import requests
url = "https://audit.basaltic.sh/v1/audit-logs"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://audit.basaltic.sh/v1/audit-logs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://audit.basaltic.sh/v1/audit-logs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://audit.basaltic.sh/v1/audit-logs"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://audit.basaltic.sh/v1/audit-logs")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://audit.basaltic.sh/v1/audit-logs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"audit_logs": [
{
"crn": "crn:audit:::log/550e8400-e29b-41d4-a716-446655440000",
"id": "e5f6a7b8-c9d0-1234-5678-90abcdef1234",
"timestamp": "2026-01-15T09:30:00Z",
"actor_crn": "crn:workspace:::organization/7c9e6679-7425-40de-944b-e07fc1f90ae7/user/550e8400-e29b-41d4-a716-446655440000",
"resource_crn": "crn:workspace:::organization/550e8400-e29b-41d4-a716-446655440000",
"actor_name": "John Doe",
"actor_email": "john.doe@acme.com",
"action": "iam.policy.create",
"status": "success",
"resource_name": "web-server-1",
"ip_address": "192.168.1.100",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
"request_id": "req-7c9e6679742540de",
"details": {},
"error_code": "access_denied",
"error_message": "Principal is not authorized to perform this action"
}
],
"meta": {
"total": 150,
"limit": 20,
"marker": "550e8400-e29b-41d4-a716-446655440000",
"has_more": true
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "ACCESS_DENIED",
"message": "You don't have permission to perform this action",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}audit:ListLogs. Consulte permisos de auditoría para obtener la lista completa, lo que cubre cada una y un ejemplo de política.Autorizaciones
Un token bearer de OAuth 2.0, enviado como Authorization: Bearer <token>. Esta es la forma recomendada de autenticación.
Obtén el token intercambiando el par de claves de acceso de una cuenta de servicio en POST /v1/oauth/token con grant_type=client_credentials. Es el flujo estándar de credenciales de cliente; las bibliotecas compatibles con OAuth pueden obtener y renovar el token por ti.
curl -s -u "$KEY_ID:$SECRET" -d grant_type=client_credentials \
https://iam.basaltic.sh/v1/oauth/token
Los tokens duran una hora por defecto. El mismo par de claves de acceso también sirve como credencial AWS SigV4 para el endpoint de objetos compatible con S3, que solo acepta ese método de autenticación.
Parámetros de consulta
CRN de evento de auditoría exacto (crn:audit:::log/UUID). Las identidades extranjeras o no coincidentes producen una página en blanco. Esto selecciona el evento en sí, independientemente de las instantáneas de recursos y actores.
Filtra por un UUID canónico o un CRN de actor exacto en el momento del evento, incluidos los usuarios de Workspace, las identidades de IAM de la cuenta y los CRN históricos retenidos. Coincide identidades almacenadas con eventos en la organización actual, incluidos actores eliminados. No se admiten nombres simples ni CRN de comodín. Los eventos sin un CRN almacenado siguen siendo buscables por UUID.
"550e8400-e29b-41d4-a716-446655440000"
Filtrar por tipo de actor
user, service_account, system "user"
Filtrar por acción (concordancia exacta o prefijo con comodín, por ejemplo, "iam.*")
"iam.policy.create"
Filtrar por tipo de recurso
"instance"
Filtra por un UUID canónico o un CRN de recurso en tiempo de evento, sin buscar un recurso activo. Un CRN coincide exactamente y también coincide con descendientes en un límite literal /: crn:network:region:account:vpc/prod coincide con crn:network:region:account:vpc/prod/subnet/private almacenado. La cuenta y la región coinciden exactamente dentro de la organización actual. Los caracteres de porcentaje y subrayado son literales, no comodines. No se admiten nombres simples ni CRN de comodín. Los eventos sin un CRN almacenado siguen siendo buscables por UUID. El filtro resource_type se aplica de forma independiente, incluso a los eventos descendientes.
"crn:network:sa-saopaulo-1:acme:vpc/prod"
Filtrar por estado
success, failure, denied "success"
Filtrar por dirección IP
"192.168.1.100"
Filtrar registros desde esta marca de tiempo (inclusive)
"2026-01-01T00:00:00Z"
Filtrar registros hasta esta marca de tiempo (exclusivo)
"2026-02-01T00:00:00Z"
Número máximo de artículos a devolver. Un valor por encima del máximo se le aplica en lugar de rechazarlo, por lo que una página más corta que la que solicitaste es normal — page until meta.has_more es falso, no hasta que una página se vea corta.
1 <= x <= 100Cursor de paginación opaco. Hacer eco del valor meta.marker de la página anterior para buscar la siguiente; no construirlo ni analizarlo. La forma interna del token varía según el punto final (un ID de recurso, una marca de tiempo, etc.) y no se garantiza su estabilidad entre versiones.

