curl --request POST \
--url https://use.hoop.dev/api/sidecars/reviews \
--header 'Content-Type: application/json' \
--data '
{
"approval_rule": "payments-approvers",
"listener_name": "appdb",
"payload": "REVMRVRFIEZST00gdXNlcnM7",
"reserve": false
}
'import requests
url = "https://use.hoop.dev/api/sidecars/reviews"
payload = {
"approval_rule": "payments-approvers",
"listener_name": "appdb",
"payload": "REVMRVRFIEZST00gdXNlcnM7",
"reserve": False
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
approval_rule: 'payments-approvers',
listener_name: 'appdb',
payload: 'REVMRVRFIEZST00gdXNlcnM7',
reserve: false
})
};
fetch('https://use.hoop.dev/api/sidecars/reviews', 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://use.hoop.dev/api/sidecars/reviews",
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([
'approval_rule' => 'payments-approvers',
'listener_name' => 'appdb',
'payload' => 'REVMRVRFIEZST00gdXNlcnM7',
'reserve' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$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://use.hoop.dev/api/sidecars/reviews"
payload := strings.NewReader("{\n \"approval_rule\": \"payments-approvers\",\n \"listener_name\": \"appdb\",\n \"payload\": \"REVMRVRFIEZST00gdXNlcnM7\",\n \"reserve\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
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://use.hoop.dev/api/sidecars/reviews")
.header("Content-Type", "application/json")
.body("{\n \"approval_rule\": \"payments-approvers\",\n \"listener_name\": \"appdb\",\n \"payload\": \"REVMRVRFIEZST00gdXNlcnM7\",\n \"reserve\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://use.hoop.dev/api/sidecars/reviews")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"approval_rule\": \"payments-approvers\",\n \"listener_name\": \"appdb\",\n \"payload\": \"REVMRVRFIEZST00gdXNlcnM7\",\n \"reserve\": false\n}"
response = http.request(request)
puts response.read_body{
"forward": false,
"review": {
"access_duration": 0,
"access_request_rule_name": "default-access-request-rule",
"approval_ttl_sec": 600,
"connection": {
"id": "20A5AABE-C35D-4F04-A5A7-C856EE6C7703",
"name": "pgdemo"
},
"created_at": "2024-07-25T15:56:35.317601Z",
"expires_at": "2024-07-25T16:11:35.000Z",
"force_approval_groups": [
"sre-team"
],
"id": "9F9745B4-C77B-4D52-84D3-E24F67E3623C",
"listener_name": "appdb",
"min_approvals": 2,
"rejection_reason": "This command is not allowed in production.",
"review_groups_data": [
{
"forced_review": false,
"group": "sre",
"id": "20A5AABE-C35D-4F04-A5A7-C856EE6C7703",
"review_date": "2024-07-25T19:36:41Z",
"reviewed_by": {
"email": "john.wick@bad.org",
"id": "D5BFA2DD-7A09-40AE-AFEB-C95787BA9E90",
"name": "John Wick",
"slack_id": "U053ELZHB53"
},
"status": "APPROVED"
}
],
"revoke_at": "",
"session": "35DB0A2F-E5CE-4AD8-A308-55C3108956E5",
"sidecar_id": "5F5E5C6E-6C3A-4E9A-9E8B-2D6A7F1B0C4D",
"status": "PENDING",
"time_window": {
"configuration": {
"end_time": "18:00",
"start_time": "09:00"
},
"type": "time_range"
},
"type": "onetime"
}
}{
"forward": false,
"review": {
"access_duration": 0,
"access_request_rule_name": "default-access-request-rule",
"approval_ttl_sec": 600,
"connection": {
"id": "20A5AABE-C35D-4F04-A5A7-C856EE6C7703",
"name": "pgdemo"
},
"created_at": "2024-07-25T15:56:35.317601Z",
"expires_at": "2024-07-25T16:11:35.000Z",
"force_approval_groups": [
"sre-team"
],
"id": "9F9745B4-C77B-4D52-84D3-E24F67E3623C",
"listener_name": "appdb",
"min_approvals": 2,
"rejection_reason": "This command is not allowed in production.",
"review_groups_data": [
{
"forced_review": false,
"group": "sre",
"id": "20A5AABE-C35D-4F04-A5A7-C856EE6C7703",
"review_date": "2024-07-25T19:36:41Z",
"reviewed_by": {
"email": "john.wick@bad.org",
"id": "D5BFA2DD-7A09-40AE-AFEB-C95787BA9E90",
"name": "John Wick",
"slack_id": "U053ELZHB53"
},
"status": "APPROVED"
}
],
"revoke_at": "",
"session": "35DB0A2F-E5CE-4AD8-A308-55C3108956E5",
"sidecar_id": "5F5E5C6E-6C3A-4E9A-9E8B-2D6A7F1B0C4D",
"status": "PENDING",
"time_window": {
"configuration": {
"end_time": "18:00",
"start_time": "09:00"
},
"type": "time_range"
},
"type": "onetime"
}
}{
"message": "the error description"
}{
"message": "the error description"
}{
"message": "the error description"
}{
"message": "the error description"
}{
"message": "the error description"
}Create Sidecar Approval Request
Register an approval request for a statement a sidecar held. The sidecar is taken from the token, never the body. An approval request for the same bytes past its deadline is expired and a new one is filed.
curl --request POST \
--url https://use.hoop.dev/api/sidecars/reviews \
--header 'Content-Type: application/json' \
--data '
{
"approval_rule": "payments-approvers",
"listener_name": "appdb",
"payload": "REVMRVRFIEZST00gdXNlcnM7",
"reserve": false
}
'import requests
url = "https://use.hoop.dev/api/sidecars/reviews"
payload = {
"approval_rule": "payments-approvers",
"listener_name": "appdb",
"payload": "REVMRVRFIEZST00gdXNlcnM7",
"reserve": False
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
approval_rule: 'payments-approvers',
listener_name: 'appdb',
payload: 'REVMRVRFIEZST00gdXNlcnM7',
reserve: false
})
};
fetch('https://use.hoop.dev/api/sidecars/reviews', 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://use.hoop.dev/api/sidecars/reviews",
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([
'approval_rule' => 'payments-approvers',
'listener_name' => 'appdb',
'payload' => 'REVMRVRFIEZST00gdXNlcnM7',
'reserve' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$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://use.hoop.dev/api/sidecars/reviews"
payload := strings.NewReader("{\n \"approval_rule\": \"payments-approvers\",\n \"listener_name\": \"appdb\",\n \"payload\": \"REVMRVRFIEZST00gdXNlcnM7\",\n \"reserve\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
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://use.hoop.dev/api/sidecars/reviews")
.header("Content-Type", "application/json")
.body("{\n \"approval_rule\": \"payments-approvers\",\n \"listener_name\": \"appdb\",\n \"payload\": \"REVMRVRFIEZST00gdXNlcnM7\",\n \"reserve\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://use.hoop.dev/api/sidecars/reviews")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"approval_rule\": \"payments-approvers\",\n \"listener_name\": \"appdb\",\n \"payload\": \"REVMRVRFIEZST00gdXNlcnM7\",\n \"reserve\": false\n}"
response = http.request(request)
puts response.read_body{
"forward": false,
"review": {
"access_duration": 0,
"access_request_rule_name": "default-access-request-rule",
"approval_ttl_sec": 600,
"connection": {
"id": "20A5AABE-C35D-4F04-A5A7-C856EE6C7703",
"name": "pgdemo"
},
"created_at": "2024-07-25T15:56:35.317601Z",
"expires_at": "2024-07-25T16:11:35.000Z",
"force_approval_groups": [
"sre-team"
],
"id": "9F9745B4-C77B-4D52-84D3-E24F67E3623C",
"listener_name": "appdb",
"min_approvals": 2,
"rejection_reason": "This command is not allowed in production.",
"review_groups_data": [
{
"forced_review": false,
"group": "sre",
"id": "20A5AABE-C35D-4F04-A5A7-C856EE6C7703",
"review_date": "2024-07-25T19:36:41Z",
"reviewed_by": {
"email": "john.wick@bad.org",
"id": "D5BFA2DD-7A09-40AE-AFEB-C95787BA9E90",
"name": "John Wick",
"slack_id": "U053ELZHB53"
},
"status": "APPROVED"
}
],
"revoke_at": "",
"session": "35DB0A2F-E5CE-4AD8-A308-55C3108956E5",
"sidecar_id": "5F5E5C6E-6C3A-4E9A-9E8B-2D6A7F1B0C4D",
"status": "PENDING",
"time_window": {
"configuration": {
"end_time": "18:00",
"start_time": "09:00"
},
"type": "time_range"
},
"type": "onetime"
}
}{
"forward": false,
"review": {
"access_duration": 0,
"access_request_rule_name": "default-access-request-rule",
"approval_ttl_sec": 600,
"connection": {
"id": "20A5AABE-C35D-4F04-A5A7-C856EE6C7703",
"name": "pgdemo"
},
"created_at": "2024-07-25T15:56:35.317601Z",
"expires_at": "2024-07-25T16:11:35.000Z",
"force_approval_groups": [
"sre-team"
],
"id": "9F9745B4-C77B-4D52-84D3-E24F67E3623C",
"listener_name": "appdb",
"min_approvals": 2,
"rejection_reason": "This command is not allowed in production.",
"review_groups_data": [
{
"forced_review": false,
"group": "sre",
"id": "20A5AABE-C35D-4F04-A5A7-C856EE6C7703",
"review_date": "2024-07-25T19:36:41Z",
"reviewed_by": {
"email": "john.wick@bad.org",
"id": "D5BFA2DD-7A09-40AE-AFEB-C95787BA9E90",
"name": "John Wick",
"slack_id": "U053ELZHB53"
},
"status": "APPROVED"
}
],
"revoke_at": "",
"session": "35DB0A2F-E5CE-4AD8-A308-55C3108956E5",
"sidecar_id": "5F5E5C6E-6C3A-4E9A-9E8B-2D6A7F1B0C4D",
"status": "PENDING",
"time_window": {
"configuration": {
"end_time": "18:00",
"start_time": "09:00"
},
"type": "time_range"
},
"type": "onetime"
}
}{
"message": "the error description"
}{
"message": "the error description"
}{
"message": "the error description"
}{
"message": "the error description"
}{
"message": "the error description"
}Headers
The token returned when the sidecar was created. Omit it when sending hoop-sidecar-identity.
A Kubernetes or Google service account JWT, raw, that a sidecar service account mapping allows. Omit it when sending hoop-sidecar-token.
Body
The request body resource
The access request rule that decides who may approve this statement
It must be the rule the sidecar's stored configuration names for this listener. The rule carries the approver groups, the approval count and the force-approval list; the sidecar holds none of that policy and only names it.
Bounded at 254 to match what a rule name may be.
254"payments-approvers"
The sidecar listener the statement arrived on, at most 1024 bytes
"appdb"
The statement to approve, base64 encoded
"REVMRVRFIEZST00gdXNlcnM7"
Reserve an approved request instead of spending it
The review moves to PROCESSING, and the sidecar settles it with what the upstream answered. A plane that predates this field ignores it and spends the approval at release.
false
Response
OK
Whether the sidecar may release the statement it held
True only on the request that consumed or reserved an approved request, and only once per claim. False while the approval request waits or a reservation is in flight, and false forever once it is rejected, revoked or expired.
false
The approval request the statement is waiting on, or the one that released it
Show child attributes
Show child attributes
Was this page helpful?