Skip to main content

Overview

When you make an API call with your alf_ key, the request travels through a secure proxy layer before reaching your Alfred. This guide explains the full request lifecycle and the security model behind it.

The request path

In plain terms:
Your Script (alf_xxx) --> SaaS Proxy --> Tailscale --> Your Alfred --> Services

Step-by-step breakdown

1. You send a request with your API key

You create API keys in your dashboard under Settings > API Keys. Each key starts with alf_ followed by 32 hex characters:
curl -X GET /api/v1/vault/context \
  -H "Authorization: Bearer alf_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"
Your request hits the SaaS server at alfred.black.

2. The proxy authenticates your key

The proxy extracts the Bearer token from the Authorization header and validates the alf_ prefix. It then computes a SHA-256 hash of the full key and looks it up in the ApiKey database table. The raw key is never stored — only its hash. This means even if the database were compromised, your API keys could not be recovered.
alf_a1b2c3d4... --> SHA-256 --> keyHash --> ApiKey table lookup
If the key is valid, the proxy loads the associated account and locates your Alfred. The lastUsedAt timestamp on the key is updated asynchronously.

3. The proxy validates readiness

Before forwarding, the proxy checks three conditions:
CheckError if failed
Alfred exists404 — No Alfred found
Tailscale hostname and internal key are set503 — Not ready yet
Status is running503 — Not running

4. The internal key is decrypted

Your Alfred’s internal API key (used for communication between the SaaS and your Alfred) is stored encrypted using AES-256-GCM. The proxy decrypts it at request time using a server-side encryption key. The encrypted format is iv:authTag:ciphertext, providing both confidentiality and integrity verification.

5. The request is forwarded via Tailscale

The proxy constructs a URL using your Alfred’s Tailscale hostname and forwards the request:
https://{tailscaleHostname}:3100/api/v1/vault/context
The forwarded request includes:
  • The decrypted internal key as a Bearer token
  • The original request method (GET, POST, PATCH, DELETE)
  • The original request body (for non-GET requests)
  • Query parameters from the original request
A 15-second timeout is enforced on the forwarded request.

6. Your Alfred authenticates and executes

Your Alfred’s API server (alfred-ctrl running on port 3100) receives the request and authenticates it against its own internal key. If valid, it executes the operation — which may involve running CLI commands, managing services, or reading and writing vault files.

7. The response flows back

Your Alfred’s response (status code, headers, and body) flows back through Tailscale to the SaaS proxy, which forwards it to your script unchanged. JSON responses are parsed and re-serialized; non-JSON responses are passed through as-is.

Two proxy paths

The SaaS server exposes two URL patterns that both route through the same proxy logic:
Path patternDescription
/api/v1/...Primary API path. The URL is forwarded as-is.
/user-api/...Legacy path. The prefix is stripped and rewritten to /api/v1/... before forwarding.
Both paths use the same authentication and proxy logic. Use /api/v1/... for all new integrations.

Error handling

The proxy translates errors at each stage:
ScenarioHTTP StatusError message
Missing Authorization header401Missing or invalid Authorization header
Key doesn’t start with alf_401Invalid API key format
Key hash not found in database401Invalid API key
No Alfred provisioned404No instance found
Not ready or not running503Instance is not ready / not running
Request timed out (15s)504Request timed out
Unreachable502Failed to reach instance
Errors from your Alfred itself (400, 404, 500, etc.) are passed through with their original status codes.

Security model

The proxy layer provides several security guarantees:
  • No raw key storage — API keys are hashed with SHA-256 before storage. The full key is shown only once at creation time.
  • Encrypted internal credentials — The internal API key is encrypted at rest with AES-256-GCM. It is decrypted only in memory during request forwarding.
  • Network isolation — Your Alfred is accessible only via Tailscale, a WireGuard-based mesh VPN. It is not exposed to the public internet.
  • Scoped authentication — Your alf_ key authenticates you to the SaaS. The SaaS uses a separate, internal key to authenticate to your Alfred. These credentials are independent.
  • Key limits — Each account can have at most 10 API keys, reducing the attack surface.

API Keys Guide

Creating and managing your API keys

Authentication Reference

API authentication details