Presigned URLs to approve/deny actions (shutdown, rollback, cache flush) without sharing master tokens.
You need to get approval before performing critical operations like shutting down a service, rolling back a deployment, or flushing a cache. Sharing your master credentials with approvers is a security risk, and building a custom approval system is overkill.
You want a simple way to send approval links via Slack or email that expire after use or timeout.
Use presigned URLs to create time-limited approval links. When clicked, they update a value in your stash that your automation can poll. No credentials exposed, no custom backend needed.
Create a stash to track approval decisions:
# Create your stash
curl -X POST https://wrendb.com/api/stash
{
"stash_id": "abc123...",
"master_token": "token-xyz789...",
"message": "Save this token securely..."
}
# Store these in your environment
export APPROVAL_STASH_ID="abc123..."
export APPROVAL_TOKEN="token-xyz789..."
Create presigned URLs for approve/deny actions:
#!/bin/bash
STASH_ID="$APPROVAL_STASH_ID"
TOKEN="$APPROVAL_TOKEN"
ACTION_ID="cache-flush-$(date +%s)"
# Generate approve URL
APPROVE_URL=$(curl -X POST "https://wrendb.com/api/item/$STASH_ID/$ACTION_ID/presign" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: text/plain" \
-d "approved" | jq -r '.url')
# Generate deny URL
DENY_URL=$(curl -X POST "https://wrendb.com/api/item/$STASH_ID/$ACTION_ID/presign" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: text/plain" \
-d "denied" | jq -r '.url')
echo "Approve: $APPROVE_URL"
echo "Deny: $DENY_URL"
# Send to Slack or email
curl -X POST https://hooks.slack.com/services/YOUR/WEBHOOK/URL \
-H 'Content-Type: application/json' \
-d "{\"text\": \"Approval needed for cache flush:\n✅ <$APPROVE_URL|Approve>\n❌ <$DENY_URL|Deny>\"}"
Your automation waits for a decision:
#!/bin/bash
STASH_ID="$APPROVAL_STASH_ID"
ACTION_ID="$1" # Pass action ID as argument
TIMEOUT=900 # 15 minutes
ELAPSED=0
echo "Waiting for approval on $ACTION_ID..."
while [ $ELAPSED -lt $TIMEOUT ]; do
# Check the decision
DECISION=$(curl -s "https://wrendb.com/api/item/$STASH_ID/$ACTION_ID" 2>/dev/null)
if [ "$DECISION" = "approved" ]; then
echo "✅ Approved! Proceeding with action..."
# Execute your critical operation here
flush_cache
exit 0
elif [ "$DECISION" = "denied" ]; then
echo "❌ Denied. Aborting action."
exit 1
fi
sleep 10
ELAPSED=$((ELAPSED + 10))
done
echo "⏱️ Timeout: No decision received. Aborting."
exit 1
import os
import time
import requests
from datetime import datetime
STASH_ID = os.environ["APPROVAL_STASH_ID"]
TOKEN = os.environ["APPROVAL_TOKEN"]
BASE_URL = f"https://wrendb.com/api/item/{STASH_ID}"
def create_approval_request(action_name):
"""Generate approve/deny URLs"""
action_id = f"{action_name}-{int(time.time())}"
# Generate approve URL
approve_resp = requests.post(
f"{BASE_URL}/{action_id}/presign",
headers={"Authorization": f"Bearer {TOKEN}"},
data="approved"
)
approve_url = approve_resp.json()["url"]
# Generate deny URL
deny_resp = requests.post(
f"{BASE_URL}/{action_id}/presign",
headers={"Authorization": f"Bearer {TOKEN}"},
data="denied"
)
deny_url = deny_resp.json()["url"]
return action_id, approve_url, deny_url
def wait_for_decision(action_id, timeout=900):
"""Poll for approval decision"""
start = time.time()
while time.time() - start < timeout:
try:
response = requests.get(f"{BASE_URL}/{action_id}")
if response.status_code == 200:
decision = response.text
if decision == "approved":
return "approved"
elif decision == "denied":
return "denied"
except Exception as e:
pass
time.sleep(10)
return "timeout"
# Example usage
if __name__ == "__main__":
action_id, approve_url, deny_url = create_approval_request("cache-flush")
print(f"Approval needed for cache flush:")
print(f"✅ Approve: {approve_url}")
print(f"❌ Deny: {deny_url}")
# Send to Slack here...
decision = wait_for_decision(action_id)
if decision == "approved":
print("✅ Approved! Proceeding...")
# Execute critical operation
elif decision == "denied":
print("❌ Denied. Aborting.")
else:
print("⏱️ Timeout. Aborting.")