curl --request POST \
--url https://{host}/v1/admin/credentials \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--header 'X-Ambient-Actor: <api-key>' \
--header 'X-Ambient-Timestamp: <api-key>' \
--data '
{
"commandId": "<string>",
"credentialId": "<string>",
"subjectPrincipalId": "<string>",
"type": "<string>",
"claims": {},
"validUntil": "2023-11-07T05:31:56Z"
}
'import requests
url = "https://{host}/v1/admin/credentials"
payload = {
"commandId": "<string>",
"credentialId": "<string>",
"subjectPrincipalId": "<string>",
"type": "<string>",
"claims": {},
"validUntil": "2023-11-07T05:31:56Z"
}
headers = {
"X-Ambient-Actor": "<api-key>",
"X-Ambient-Timestamp": "<api-key>",
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Ambient-Actor': '<api-key>',
'X-Ambient-Timestamp': '<api-key>',
Authorization: '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
commandId: '<string>',
credentialId: '<string>',
subjectPrincipalId: '<string>',
type: '<string>',
claims: {},
validUntil: '2023-11-07T05:31:56Z'
})
};
fetch('https://{host}/v1/admin/credentials', 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://{host}/v1/admin/credentials",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'commandId' => '<string>',
'credentialId' => '<string>',
'subjectPrincipalId' => '<string>',
'type' => '<string>',
'claims' => [
],
'validUntil' => '2023-11-07T05:31:56Z'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json",
"X-Ambient-Actor: <api-key>",
"X-Ambient-Timestamp: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{host}/v1/admin/credentials"
payload := strings.NewReader("{\n \"commandId\": \"<string>\",\n \"credentialId\": \"<string>\",\n \"subjectPrincipalId\": \"<string>\",\n \"type\": \"<string>\",\n \"claims\": {},\n \"validUntil\": \"2023-11-07T05:31:56Z\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Ambient-Actor", "<api-key>")
req.Header.Add("X-Ambient-Timestamp", "<api-key>")
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{host}/v1/admin/credentials")
.header("X-Ambient-Actor", "<api-key>")
.header("X-Ambient-Timestamp", "<api-key>")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"commandId\": \"<string>\",\n \"credentialId\": \"<string>\",\n \"subjectPrincipalId\": \"<string>\",\n \"type\": \"<string>\",\n \"claims\": {},\n \"validUntil\": \"2023-11-07T05:31:56Z\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{host}/v1/admin/credentials")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Ambient-Actor"] = '<api-key>'
request["X-Ambient-Timestamp"] = '<api-key>'
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"commandId\": \"<string>\",\n \"credentialId\": \"<string>\",\n \"subjectPrincipalId\": \"<string>\",\n \"type\": \"<string>\",\n \"claims\": {},\n \"validUntil\": \"2023-11-07T05:31:56Z\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"issuerPrincipalId": "<string>",
"issuingActorId": "<string>",
"subjectPrincipalId": "<string>",
"type": "<string>",
"claims": {},
"issuedAt": "2023-11-07T05:31:56Z",
"signingKeyId": "<string>",
"payloadVersion": "ambient-credential.v1",
"signature": "<string>",
"authorityRef": "<string>",
"validUntil": "2023-11-07T05:31:56Z",
"revokedAt": "2023-11-07T05:31:56Z"
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "unauthenticated",
"message": "request authentication failed"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}Issue an Ed25519-signed Ambient credential
Creates an ambient-credential.v1 envelope for an existing subject
principal. The authenticated actor must equal the issuing actor in
AMBIENT_CREDENTIAL_ISSUER. Ambient controls issuer identity, signing
key, and issue time; verifies the resulting proof against the registered
public key; and atomically records the credential and command decision.
This is not yet a portable W3C Verifiable Credential.
curl --request POST \
--url https://{host}/v1/admin/credentials \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--header 'X-Ambient-Actor: <api-key>' \
--header 'X-Ambient-Timestamp: <api-key>' \
--data '
{
"commandId": "<string>",
"credentialId": "<string>",
"subjectPrincipalId": "<string>",
"type": "<string>",
"claims": {},
"validUntil": "2023-11-07T05:31:56Z"
}
'import requests
url = "https://{host}/v1/admin/credentials"
payload = {
"commandId": "<string>",
"credentialId": "<string>",
"subjectPrincipalId": "<string>",
"type": "<string>",
"claims": {},
"validUntil": "2023-11-07T05:31:56Z"
}
headers = {
"X-Ambient-Actor": "<api-key>",
"X-Ambient-Timestamp": "<api-key>",
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Ambient-Actor': '<api-key>',
'X-Ambient-Timestamp': '<api-key>',
Authorization: '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
commandId: '<string>',
credentialId: '<string>',
subjectPrincipalId: '<string>',
type: '<string>',
claims: {},
validUntil: '2023-11-07T05:31:56Z'
})
};
fetch('https://{host}/v1/admin/credentials', 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://{host}/v1/admin/credentials",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'commandId' => '<string>',
'credentialId' => '<string>',
'subjectPrincipalId' => '<string>',
'type' => '<string>',
'claims' => [
],
'validUntil' => '2023-11-07T05:31:56Z'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json",
"X-Ambient-Actor: <api-key>",
"X-Ambient-Timestamp: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{host}/v1/admin/credentials"
payload := strings.NewReader("{\n \"commandId\": \"<string>\",\n \"credentialId\": \"<string>\",\n \"subjectPrincipalId\": \"<string>\",\n \"type\": \"<string>\",\n \"claims\": {},\n \"validUntil\": \"2023-11-07T05:31:56Z\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Ambient-Actor", "<api-key>")
req.Header.Add("X-Ambient-Timestamp", "<api-key>")
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{host}/v1/admin/credentials")
.header("X-Ambient-Actor", "<api-key>")
.header("X-Ambient-Timestamp", "<api-key>")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"commandId\": \"<string>\",\n \"credentialId\": \"<string>\",\n \"subjectPrincipalId\": \"<string>\",\n \"type\": \"<string>\",\n \"claims\": {},\n \"validUntil\": \"2023-11-07T05:31:56Z\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{host}/v1/admin/credentials")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Ambient-Actor"] = '<api-key>'
request["X-Ambient-Timestamp"] = '<api-key>'
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"commandId\": \"<string>\",\n \"credentialId\": \"<string>\",\n \"subjectPrincipalId\": \"<string>\",\n \"type\": \"<string>\",\n \"claims\": {},\n \"validUntil\": \"2023-11-07T05:31:56Z\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"issuerPrincipalId": "<string>",
"issuingActorId": "<string>",
"subjectPrincipalId": "<string>",
"type": "<string>",
"claims": {},
"issuedAt": "2023-11-07T05:31:56Z",
"signingKeyId": "<string>",
"payloadVersion": "ambient-credential.v1",
"signature": "<string>",
"authorityRef": "<string>",
"validUntil": "2023-11-07T05:31:56Z",
"revokedAt": "2023-11-07T05:31:56Z"
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "unauthenticated",
"message": "request authentication failed"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}Authorizations
Provisioned actor identifier.
Current Unix timestamp in seconds, within the configured clock-skew window.
Ambient-HMAC followed by a space and the unpadded base64url HMAC-SHA256 signature. See Authentication and authority for the canonical input.
Body
Actor-scoped idempotency key. Retry the identical command with the same value.
11Principal represented by the authenticated actor.
11Response
Credential signed and stored, or an identical command replayed.
Principal represented by the authenticated actor.
1Principal represented by the authenticated actor.
1"ambient-credential.v1"Unpadded base64url Ed25519 signature over the canonical Ambient credential payload.