curl --request PUT \
--url https://use.hoop.dev/api/sessions/{session_id}/approval \
--header 'Content-Type: application/json' \
--data '
{
"status": "APPROVED",
"force_review": false,
"rejection_reason": "This command is not allowed in production."
}
'import requests
url = "https://use.hoop.dev/api/sessions/{session_id}/approval"
payload = {
"status": "APPROVED",
"force_review": False,
"rejection_reason": "This command is not allowed in production."
}
headers = {"Content-Type": "application/json"}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
status: 'APPROVED',
force_review: false,
rejection_reason: 'This command is not allowed in production.'
})
};
fetch('https://use.hoop.dev/api/sessions/{session_id}/approval', 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/sessions/{session_id}/approval",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'status' => 'APPROVED',
'force_review' => false,
'rejection_reason' => 'This command is not allowed in production.'
]),
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/sessions/{session_id}/approval"
payload := strings.NewReader("{\n \"status\": \"APPROVED\",\n \"force_review\": false,\n \"rejection_reason\": \"This command is not allowed in production.\"\n}")
req, _ := http.NewRequest("PUT", 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.put("https://use.hoop.dev/api/sessions/{session_id}/approval")
.header("Content-Type", "application/json")
.body("{\n \"status\": \"APPROVED\",\n \"force_review\": false,\n \"rejection_reason\": \"This command is not allowed in production.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://use.hoop.dev/api/sessions/{session_id}/approval")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"status\": \"APPROVED\",\n \"force_review\": false,\n \"rejection_reason\": \"This command is not allowed in production.\"\n}"
response = http.request(request)
puts response.read_body{
"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"
}Update Approval Status By Sid
Update the status of an approval request resource by its resource ID or session ID. This endpoint is used to approve, reject, or revoke approval requests for session execution requests.
Overview
When a user interacts with a session, an approval request resource is automatically created containing the configured approver groups, each initially set to PENDING status. All groups must be approved before the session can be executed.
The approval status updates affect each approver group based on the caller’s context. Once all groups are APPROVED, or if any group becomes REJECTED or REVOKED, the overall resource status updates accordingly.
Approver Groups
Approver groups contain individual approval entries that must be completed by authorized users from specific groups. Each entry represents a required approval from a designated approver group.
Initial State
When an approval request is created, each group entry is populated with the following structure:
{
"id": "aaa257be-5cc9-401d-ae7e-18ae806d366a",
"group": "banking",
"status": "PENDING",
"reviewed_by": null,
"review_date": null
}
Completed Approval State
After an approval entry is completed, it includes the status, decision timestamp, and approver information:
{
"id": "a546dfba-d917-4c2b-bc38-7852a7932573",
"group": "banking",
"status": "REJECTED",
"reviewed_by": {
"id": "17e4ff1a-104c-482c-be68-3c01bfc7028e",
"name": "John Doe",
"email": "john.doe@domain.tld",
"slack_id": ""
},
"review_date": "2025-05-27T16:40:05.519754143Z"
}
Approval States
User-Controlled States
These states are set directly by approvers:
APPROVED- The resource has been approved by the approverREJECTED- The resource is rejected and cannot be updated furtherREVOKED- The resource is revoked and cannot be updated further
System-Controlled States
These states are managed automatically by the gateway:
PENDING- Initial state when the approval request is createdPROCESSING- Session is being executed; approval request cannot be updatedEXECUTED- Session completed successfully; approval request cannot be updatedUNKNOWN- Session executed but outcome is indeterminateEXPIRED- A sidecar approval request passed itsexpires_atbefore it was decided or used; nothing was released. Only a control plane sets it
General Rules
Approval Permissions
- An approval request the user cannot get with
GET /reviews/{id}answers404, the same as an approval request that does not exist - Approvals can only be decided when the resource status is
PENDINGorAPPROVED - Resource owners cannot self-approve - approval requires another member of the same group
- Users are only eligible to approve if they are not the resource owner or are administrators
Multi-Group Approvals
- If a user belongs to multiple groups, separate approval entries are updated for each group
- All group approvals must be completed before session execution
Status Transitions
- Setting any approval to
REJECTEDimmediately changes the overall resource status and prevents further updates APPROVEDapproval requests can still be changed toREJECTEDat any time by the resource owner or administratorsREVOKEDapplies only to anAPPROVEDapproval request of typejit, or to anAPPROVEDapproval request a sidecar filed (it has alistener_name). A sidecar approval request can be revoked until the sidecar uses the approval; after that it isEXECUTEDand the request answers400. A revoke of any other approval request answers400- Once an approval request reaches
REJECTEDorREVOKEDthe resource is considered as immutable and it cannot be updated again - A decision on a sidecar approval request past its
expires_atanswers400(approval request expired), and the approval request isEXPIRED
Final States
Approval requests in PROCESSING, EXECUTED, UNKNOWN, or EXPIRED states are immutable and cannot be modified.
curl --request PUT \
--url https://use.hoop.dev/api/sessions/{session_id}/approval \
--header 'Content-Type: application/json' \
--data '
{
"status": "APPROVED",
"force_review": false,
"rejection_reason": "This command is not allowed in production."
}
'import requests
url = "https://use.hoop.dev/api/sessions/{session_id}/approval"
payload = {
"status": "APPROVED",
"force_review": False,
"rejection_reason": "This command is not allowed in production."
}
headers = {"Content-Type": "application/json"}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
status: 'APPROVED',
force_review: false,
rejection_reason: 'This command is not allowed in production.'
})
};
fetch('https://use.hoop.dev/api/sessions/{session_id}/approval', 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/sessions/{session_id}/approval",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'status' => 'APPROVED',
'force_review' => false,
'rejection_reason' => 'This command is not allowed in production.'
]),
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/sessions/{session_id}/approval"
payload := strings.NewReader("{\n \"status\": \"APPROVED\",\n \"force_review\": false,\n \"rejection_reason\": \"This command is not allowed in production.\"\n}")
req, _ := http.NewRequest("PUT", 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.put("https://use.hoop.dev/api/sessions/{session_id}/approval")
.header("Content-Type", "application/json")
.body("{\n \"status\": \"APPROVED\",\n \"force_review\": false,\n \"rejection_reason\": \"This command is not allowed in production.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://use.hoop.dev/api/sessions/{session_id}/approval")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"status\": \"APPROVED\",\n \"force_review\": false,\n \"rejection_reason\": \"This command is not allowed in production.\"\n}"
response = http.request(request)
puts response.read_body{
"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"
}Path Parameters
Resource identifier of the session
Body
The request body resource
The approval status
- APPROVED - Approve the approval request
- REJECTED - Reject the approval request
- REVOKED - Revoke an approved request
APPROVED, REJECTED, REVOKED "APPROVED"
false
"This command is not allowed in production."
Show child attributes
Show child attributes
Response
OK
The amount of time (nanoseconds) to allow access to the connection. It's valid only for jit type approval requests
0
The name of the access request rule that triggered this approval request, if null means it was triggered by the review plugin
"default-access-request-rule"
The time a sidecar approval lasts, in seconds, copied from the rule at filing. Absent with no limit or on an approval request from a connection
600
The connection the approval request was filed against. On a sidecar approval request, the resource that mirrors the listener; absent while the organization has no mirror for it
Show child attributes
Show child attributes
The time the resource was created
"2024-07-25T15:56:35.317601Z"
The deadline of a sidecar approval request: to decide while PENDING, to use the approval once APPROVED. Absent with no limit or on an approval request from a connection
"2024-07-25T16:11:35.000Z"
Groups that can force approve sessions for this approval request
["sre-team"]
Resource identifier
"9F9745B4-C77B-4D52-84D3-E24F67E3623C"
The sidecar listener this approval request is bound to. Absent on an approval request that came from a connection
"appdb"
The minimum number of approvals required for this approval request
2
The reason provided by the approver when rejecting this approval request
"This command is not allowed in production."
Contains the groups that must approve this request
Show child attributes
Show child attributes
The time when this approval request was revoked
""
The id of session
"35DB0A2F-E5CE-4AD8-A308-55C3108956E5"
The sidecar that filed this approval request. Absent on an approval request that came from a connection
"5F5E5C6E-6C3A-4E9A-9E8B-2D6A7F1B0C4D"
The status of the approval request
- PENDING - The resource is waiting for approval
- APPROVED - The resource is fully approved
- REJECTED - The resource is fully rejected
- REVOKED - The resource was revoked after being approved
- PROCESSING - The approval request is being executed
- EXECUTED - The approval request was executed
- UNKNOWN - Unable to know the status of the approval request
- EXPIRED - A sidecar approval request passed its deadline; it never releases the statement
PENDING, APPROVED, REJECTED, REVOKED, PROCESSING, EXECUTED, UNKNOWN, EXPIRED The time window configuration that can execute the session
Show child attributes
Show child attributes
The type of the approval request
- onetime - Represents a one time execution
- jit - Represents a time based approval
onetime, jit Was this page helpful?