Files
paste.es/docs/secret-request.md
Malin bc9f96cbd4 feat: rebrand Hemmelig to paste.es for cloudhost.es
- Set Spanish as default language with ephemeral/encrypted privacy focus
- Translate all user-facing strings and legal pages to Spanish
- Replace Norwegian flag with Spanish flag in footer
- Remove Hemmelig/terces.cloud links, add cloudhost.es sponsorship
- Rewrite PrivacyPage: zero data collection, ephemeral design emphasis
- Rewrite TermsPage: Spanish law, RGPD, paste.es/CloudHost.es references
- Update PWA manifest, HTML meta tags, package.json branding
- Rename webhook headers to X-Paste-Event / X-Paste-Signature
- Update API docs title and contact to paste.es / cloudhost.es

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 09:30:19 +01:00

4.8 KiB

Secret Requests

Secret Requests allow you to request secrets from others securely. Instead of asking someone to create a secret and send you the link, you create a request link that they can use to submit a secret directly to you.

How It Works

  1. Create a Request - You configure the secret settings (expiration, max views, etc.) and get a unique request link
  2. Share the Link - Send the request link to the person who has the secret
  3. They Submit - They enter their secret, which gets encrypted in their browser. They receive a decryption key which they must send back to you.
  4. View the Secret - You use the secret URL from your dashboard combined with the decryption key to view the secret.
┌─────────────┐         ┌─────────────┐
│  Requester  │         │   Creator   │
│  (You)      │         │  (Them)     │
└──────┬──────┘         └──────┬──────┘
       │                       │
       │ 1. Create request     │
       │───────────────────>   │
       │                       │
       │ 2. Share request link │
       │ ─ ─ ─ ─ ─ ─ ─ ─ ─ >   │
       │                       │
       │                       │ 3. Submit secret
       │                       │    (encrypted)
       │                       │
       │ 4. They send you the  │
       │    decryption key     │
       │< ─ ─ ─ ─ ─ ─ ─ ─ ─ ─  │
       │                       │
       │ 5. View secret from   │
       │    dashboard with key │
       │                       │

Creating a Request

Navigate to Dashboard → Secret Requests → Create New Request.

Required Fields

  • Title - A descriptive title shown to the creator (e.g., "API credentials for Project X")

Optional Fields

  • Description - Additional context for the creator
  • Link Validity - How long the request link remains active (1 hour to 30 days)
  • Secret Expiration - How long the submitted secret lives (5 minutes to 28 days)
  • Max Views - Number of times the secret can be viewed (1-9999)
  • IP Restriction - Limit secret access to specific IP/CIDR
  • Prevent Burn - Keep secret even after max views reached
  • Webhook URL - Get notified when the secret is submitted

Webhooks

When a secret is submitted, Hemmelig sends a POST request to your webhook URL:

{
    "event": "secret_request.fulfilled",
    "timestamp": "2024-12-14T10:30:00.000Z",
    "request": {
        "id": "uuid",
        "title": "API credentials",
        "createdAt": "2024-12-14T10:00:00.000Z",
        "fulfilledAt": "2024-12-14T10:30:00.000Z"
    },
    "secret": {
        "id": "secret-uuid",
        "maxViews": 1,
        "expiresAt": "2024-12-15T10:30:00.000Z"
    }
}

Webhook Security

Webhooks are signed using HMAC-SHA256. Verify the signature to ensure authenticity:

const crypto = require('crypto');

function verifyWebhook(payload, signature, timestamp, secret) {
    const signedPayload = `${timestamp}.${JSON.stringify(payload)}`;
    const expectedSig = crypto.createHmac('sha256', secret).update(signedPayload).digest('hex');

    return `sha256=${expectedSig}` === signature;
}

// Headers to check:
// X-Hemmelig-Signature: sha256=<hex>
// X-Hemmelig-Timestamp: <unix-timestamp>

Note: The webhook secret is shown only once when creating the request. Store it securely.

Security

  • Client-side encryption - Secrets are encrypted in the creator's browser before transmission
  • Decryption key in URL fragment - The #decryptionKey=... never reaches the server
  • Single-use tokens - Request links use 256-bit cryptographically secure tokens
  • Timing-safe validation - Prevents timing attacks on token verification

API Usage

Create a Request

curl -X POST https://your-instance/api/secret-requests \
  -H "Authorization: Bearer hemmelig_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Database credentials",
    "description": "Need the prod DB password",
    "maxViews": 1,
    "expiresIn": 86400,
    "validFor": 604800
  }'

List Your Requests

curl https://your-instance/api/secret-requests \
  -H "Authorization: Bearer hemmelig_your_api_key"

Get Request Details

curl https://your-instance/api/secret-requests/{id} \
  -H "Authorization: Bearer hemmelig_your_api_key"

Cancel a Request

curl -X DELETE https://your-instance/api/secret-requests/{id} \
  -H "Authorization: Bearer hemmelig_your_api_key"

Limits

  • Secret size: 1 MB maximum
  • Title size: 1 KB maximum
  • Request validity: 1 hour to 30 days
  • Secret expiration: 5 minutes to 28 days