Overview
UMBREN is DDoS mitigation as a service for infrastructure that other businesses own and run: VPN providers, game server operators, hosting companies and other infrastructure owners.
You register a server address, a protocol and the ports your service listens on. Once you have proven that the infrastructure is yours, UMBREN provisions a protected endpoint on an upstream scrubbing network. Attack traffic is filtered there, and legitimate traffic is forwarded to your origin. You keep control of your service and your customers.
UMBREN is not a VPN service and does not host your service. It defends the address your service is reached on.
This documentation describes how the product behaves. It contains no capacity, coverage, latency or uptime figures. UMBREN does not publish those until they describe verified infrastructure.
Core concepts
- Organization. The account boundary. Members, endpoints, policies, credentials and billing belong to one organization. The data of each organization is isolated from every other.
- Endpoint. A service you register for protection: one origin address, one protocol, and a port or port range.
- Origin. Your server. The address where your service runs and where clean traffic is delivered.
- Protected endpoint. The address reserved for you on an upstream scrubbing network. Your users connect to it in place of the origin.
- Scrubbing provider. An upstream network that filters traffic. UMBREN connects to providers through adapters that share one contract.
- Control plane. The dashboard, the API and the systems behind them. It carries configuration and telemetry. It carries no customer traffic, and protection that is already deployed does not depend on it being available.
- Policy. A versioned description of how traffic to an endpoint is mitigated. It configures six components.
- Incident. A recorded attack: its vector, severity, peak, duration and the mitigation that was applied.
Endpoint registration
An endpoint is registered with the following fields.
| Field | Description |
|---|---|
| Service name | A name your team will recognize. It is the name a member types to authorize activation. |
| Category | Generic UDP, Generic TCP, VPN Infrastructure, Gaming Infrastructure or Other Network Service. |
| Origin IP | A single public IPv4 or IPv6 address. Private and reserved ranges are rejected. |
| Protocol | UDP or TCP. |
| Port or port range | The port, or range of ports, your service listens on. The allowance depends on your plan. |
| Preferred protection region | “auto”, or a region offered by a connected provider. |
| Connection requirements | Free-text notes about how your service needs to be reached. |
| Protection profile | Standard, Strict, WireGuard-compatible or Custom. |
The origin address, protocol and ports can only be edited while the endpoint is in DRAFT. A verified combination of origin, protocol and port range can belong to only one endpoint.
Telemetry
Telemetry is what the protection network measured for an endpoint: bandwidth, packets per second, protocol distribution, and allowed versus mitigated traffic. Historical ranges are 1 hour, 24 hours, 7 days and 30 days.
If no telemetry has been reported for an endpoint, the dashboard shows “Awaiting telemetry”. It never shows placeholder traffic.
Plans and allowances
Port allowances, the number of endpoints and some features depend on the plan of the organization. Prices are on the pricing page.
- Single IP. One protected endpoint, defined port allowances and standard monitoring.
- Multi-IP. Multiple endpoints, additional policies and extended analytics.
- Network. Advanced network configuration and higher allowances. Protection for routed infrastructure is planned as part of this plan and is not available yet.
- Enterprise. Contract-based, with custom integration and support.
Onboarding lifecycle
Every endpoint moves through the same states, in order. Nothing is sent to your origin before the testing state, and no user traffic moves before activation.
| State | Meaning |
|---|---|
DRAFT | The endpoint is registered. Nothing has been verified. |
OWNERSHIP_PENDING | Ownership verification has started. |
OWNERSHIP_VERIFIED | Ownership of the origin has been verified. |
VALIDATION_PENDING | Compatibility is being checked against connected providers and your plan. Nothing is sent to the origin. |
VALIDATED | The endpoint is compatible and can be staged. |
PROVIDER_PENDING | A protected address is being reserved upstream. This requires an active subscription. |
PROVIDER_STAGED | The protected address is reserved and the origin is configured behind it. No traffic moves. |
TESTING | The provider tests the staged path to the origin. |
READY_FOR_ACTIVATION | Tests have passed. The endpoint is waiting for activation to be authorized. |
ACTIVE | Protection is active. |
States outside the main path
| State | Meaning |
|---|---|
FAILED | An automated step failed. Retry returns the endpoint to the last stable checkpoint. |
SUSPENDED | An administrative hold placed by UMBREN staff. When the hold is lifted the endpoint returns to a stable checkpoint. An endpoint that was active must be authorized again. It never resumes straight to ACTIVE. |
DEACTIVATED | Protection has been withdrawn and the upstream reservation released. The endpoint can be reopened as a new DRAFT, which requires verifying ownership again. |
Retry after a failure
When an automated step fails the endpoint moves to FAILED. Retry returns it to the last stable checkpoint before the step that failed.
| Step that failed | Retry returns to |
|---|---|
| Ownership verification | DRAFT |
| Validation | OWNERSHIP_VERIFIED |
| Staging | VALIDATED |
| Testing | PROVIDER_STAGED |
| Activation | READY_FOR_ACTIVATION |
Ownership verification
UMBREN protects infrastructure only for whoever controls it. Entering an IP address is never accepted as proof. There are two ways to verify ownership today, and a third is planned.
Verification agent
- Start agent verification for the endpoint. The dashboard issues a one-time challenge. It is valid for 24 hours and is shown once. UMBREN stores it only as a hash.
- Run the agent on the origin server, passing the challenge.
- The agent makes one outbound HTTPS request that carries the challenge. UMBREN compares the address the request arrives from with the registered origin address. If they match, ownership is verified.
umbren-agent verify --token <challenge>If the server has more than one address, use --bind to choose the source address of the request.
umbren-agent verify --token <challenge> --bind <origin address>What the agent does and does not do:
- It makes one outbound HTTPS request. It sends the challenge and nothing else.
- It opens no port, installs nothing, and exits when the request is complete.
- UMBREN never connects to, scans or probes the origin. Verification relies only on the request your server sends.
- Each challenge allows up to 20 attempts.
Manual verification
If the agent cannot be used, submit a manual verification request: a written statement and a reference that supports it, for example an allocation letter or a provider invoice. UMBREN staff review the request.
Hosting-provider integration
Verification through a hosting provider is planned. It is not available yet.
Origin requirements
- A single public address. The origin is one public IPv4 or IPv6 address. Private and reserved ranges are rejected.
- One protocol and a defined port range. UDP or TCP, on a port or port range within the allowance of your plan.
- Outbound HTTPS, for agent verification. The server must be able to make one outbound HTTPS request. No inbound port is needed for verification.
- The request must leave from the registered address. If the server reaches the Internet from a different address than the one registered, for example behind address translation, the addresses will not match. Use
--bindwhere the server holds the address, or use manual verification. - Firewall and routing ready for clean traffic. The origin must accept clean traffic from the delivery ranges shown on the endpoint page. You confirm this before testing, and it is an activation gate.
Activation gates
Activation is the moment traffic starts to move through the protected endpoint. Every gate below must hold. There is no override.
| Gate | What it requires |
|---|---|
| Ownership verified | The origin has passed agent verification or a reviewed manual verification. |
| Compatibility established | Validation against connected providers and your plan has succeeded. |
| Provider capacity confirmed | A protected address has been reserved upstream for the endpoint. |
| Origin firewall and routing ready | You have confirmed that the origin accepts clean traffic from the delivery ranges shown on the endpoint page. |
| Connection tests passed | The tests of the staged path to the origin have passed. |
| Account in good standing | The organization is active and its subscription is in good standing. |
| Activation authorized | A member with activation rights has typed the endpoint name to approve the change. API credentials cannot authorize activation. |
| Activation available on the platform | Activation is currently available on the platform. Live protection is switched on per customer, once upstream scrubbing capacity for that customer has been confirmed. |
- Gates are checked again at the moment of activation. A gate that held earlier and no longer holds stops activation.
- Billing status alone never triggers provisioning. A paid subscription does not activate anything by itself.
- Activation is authorized by a person in the dashboard. An API credential cannot authorize it.
Mitigation policies
A mitigation policy decides what happens to traffic for an endpoint. A policy has a scope, a mode and a version history.
- Scope. One endpoint, or the whole organization.
- Mode. In
monitormode the policy is evaluated and its decisions are recorded. It is never deployed. Inenforcemode the policy is eligible for deployment. - Automatic mitigation. Opt-in for each policy. It requires enforce mode.
- Versions. Every change creates a new immutable version.
- Rollback. Rolling back restores an earlier version as a new version. Earlier versions are never altered.
- Validation. Unknown configuration fields are rejected.
Components and settings
A policy configures six components. The table lists every setting, with its default where it has one.
| Component | Setting | Value | Purpose |
|---|---|---|---|
| Packet GuardPacket validation | drop_malformed | Boolean. Default true. | Drop packets that fail validation. |
drop_fragments | Boolean. Default false. | Drop fragmented packets. | |
min_packet_bytes | Integer. Default 0. | Smallest packet accepted, in bytes. | |
max_packet_bytes | Integer. Default 1500. | Largest packet accepted, in bytes. | |
blocked_source_ports | List of ports. Default 19, 53, 123, 1900, 11211. | Source ports whose traffic is dropped. The defaults are ports commonly abused for reflection. | |
| Flood GuardFlood and rate anomaly detection | pps_threshold | Integer. 0 turns it off. | Absolute packet-rate ceiling, in packets per second. |
bps_threshold | Integer. 0 turns it off. | Absolute bandwidth ceiling. | |
baseline_multiplier | Number. Default 4. | Flags traffic above this multiple of the learned baseline. | |
sustain_seconds | Integer. Default 60. | How long an anomaly must persist before it counts. | |
udp_rate_limit_pps | Integer. | Rate limit for UDP traffic, in packets per second. | |
syn_rate_limit_pps | Integer. | Rate limit for TCP SYN packets, in packets per second. | |
| Flow GuardSession-aware analysis | protect_established_flows | Boolean. Default true. | Protect flows that are already established while limits are applied to new ones. |
max_new_flows_per_source_per_second | Integer. Default 50. | New flows one source may open per second. | |
max_concurrent_flows_per_source | Integer. Default 500. | Flows one source may hold open at once. | |
idle_timeout_seconds | Integer. Default 180. | How long a flow may stay idle before it is no longer treated as established. | |
| Protocol GuardProtocol-aware profiles | profile | generic_udp, generic_tcp or wireguard. | The protocol profile applied to the endpoint. |
enforce_handshake | Boolean. Default false. | Enforce the handshake behaviour the profile describes. | |
max_handshakes_per_source_per_minute | Integer. Default 60. | Handshakes one source may start per minute. | |
| Adaptive DefenseBaselines and escalation | baseline_window_minutes | Integer. Default 60. | Window over which the traffic baseline is learned. |
sensitivity | low, medium or high. | How readily a deviation from the baseline is scored as an anomaly. | |
max_escalation_level | 1 to 3. Default 2. | Caps the automatic response. It does not cap the severity that is reported. | |
auto_escalate | Boolean. | Allow the response to escalate automatically, up to the cap. | |
| Recovery GuardExpiry and rollback | rule_ttl_minutes | Integer. Default 30. | Lifetime of automatically applied rules. They expire when it elapses. |
quiet_period_minutes | Integer. Default 10. | How long traffic must stay normal before an incident resolves. | |
rollback_on_health_failure | Boolean. Default true. | Roll mitigation back if a health check fails. |
pps_thresholdandbps_thresholdare absolute ceilings.baseline_multiplieris relative to the learned baseline. An anomaly must persist forsustain_seconds.max_escalation_levelcaps the automatic response. It does not cap the severity that is reported for an incident.- Automatically applied rules expire after
rule_ttl_minutes. An incident resolves once traffic has stayed normal forquiet_period_minutes. - Game-specific Protocol Guard profiles are planned. They are not available yet.
Notifications and webhooks
Notifications are sent to channels. A channel is an email address, a Discord webhook or a custom webhook. The event types are listed below.
| Event type | Sent when |
|---|---|
incident.detected | An incident has been detected on an endpoint. |
incident.resolved | An incident has resolved. |
endpoint.state_changed | An endpoint has moved to a different lifecycle state. |
billing.payment_failed | A subscription payment has failed. |
billing.subscription_started | A subscription has started. |
billing.plan_changed | The plan of the organization has changed. |
billing.subscription_canceled | A subscription has been canceled. |
Custom webhooks
A custom webhook is an HTTPS POST with a JSON body. Three headers describe the delivery: the event type, a delivery identifier and a signature.
POST /your/webhook/path HTTP/1.1
Content-Type: application/json
X-Umbren-Event: incident.detected
X-Umbren-Delivery: <delivery identifier>
X-Umbren-Signature: t=<unix seconds>,v1=<hex>
{
"id": "...",
"type": "incident.detected",
"created_at": "...",
"organization_id": "...",
"data": {...}
}- Origin addresses are never included in payloads.
- Redirects are not followed. Register the final URL of your receiver.
- Deliveries are retried up to 6 attempts, with exponential backoff that starts at 30 seconds and is capped at 1 hour.
- A retried delivery can arrive more than once. Use the event
idto make your handler idempotent.
Verifying signatures
Every custom webhook is signed. The signing secret starts with whsec_ and is shown once, when the channel is created. Store it as you would any credential.
The signature header has the form t=<unix seconds>,v1=<hex>. The value of v1 is the HMAC-SHA256 of the string <t>.<raw request body>, keyed with the signing secret and encoded as hexadecimal. To verify a delivery:
- Read
tandv1from theX-Umbren-Signatureheader. - Reject the request if the timestamp is more than a few minutes old. The examples below allow five minutes.
- Compute the HMAC over the timestamp, a full stop and the raw request body. Use the bytes you received, not a parsed and re-serialized copy.
- Compare the result with the received value using a constant-time comparison.
Node.js
import crypto from "node:crypto";
const TOLERANCE_SECONDS = 300;
// rawBody must be the request body exactly as it was received,
// before any JSON parsing or re-serialization.
export function verifyUmbrenSignature(rawBody, signatureHeader, signingSecret) {
const parts = Object.fromEntries(
signatureHeader.split(",").map((part) => part.trim().split("=", 2)),
);
const timestamp = Number(parts.t);
const fresh =
Number.isFinite(timestamp) &&
Math.abs(Date.now() / 1000 - timestamp) <= TOLERANCE_SECONDS;
const expected = crypto
.createHmac("sha256", signingSecret)
.update(String(parts.t) + ".")
.update(rawBody)
.digest();
const received = Buffer.from(parts.v1 ?? "", "hex");
return (
fresh &&
received.length === expected.length &&
crypto.timingSafeEqual(received, expected)
);
}Python
import hashlib
import hmac
import time
TOLERANCE_SECONDS = 300
def verify_umbren_signature(raw_body: bytes, signature_header: str, signing_secret: str) -> bool:
"""raw_body must be the request body exactly as it was received."""
parts = dict(
item.strip().split("=", 1) for item in signature_header.split(",") if "=" in item
)
timestamp = parts.get("t", "")
received = parts.get("v1", "")
if not timestamp.isdigit():
return False
if abs(time.time() - int(timestamp)) > TOLERANCE_SECONDS:
return False
signed = timestamp.encode() + b"." + raw_body
expected = hmac.new(signing_secret.encode(), signed, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, received)API
The API is REST over HTTPS with JSON request and response bodies. The base URL is https://api.umbren.net/v1. This is the planned production address.
Authentication
Send an API credential as a bearer token with every request.
Authorization: Bearer <API credential>- Credentials have the form
umb_<prefix>_<secret>and are created under Settings, then API credentials. - A credential is scoped to one organization.
- A credential carries a role:
viewer, which is read-only, orengineer. - The credential is shown once, when it is created.
- API credentials are a plan feature.
- An API credential cannot authorize activation.
Errors
Errors share one shape. Include the request_id when you contact UMBREN about a failed request.
{
"error": {
"code": "validation_failed",
"message": "...",
"fields": { "origin_ip": "..." },
"request_id": "..."
}
}| Status | Code | Meaning |
|---|---|---|
| 401 | unauthenticated | The credential is missing or not valid. |
| 403 | forbidden | The credential is valid but its role does not allow the request. |
| 404 | not_found | The resource does not exist. Also returned for resources that belong to another organization. |
| 409 | See the response body | The request is not valid in the current state of the resource, for example an invalid lifecycle transition. |
| 422 | validation_failed | The request body failed validation. The “fields” object names each field that was rejected. |
| 429 | rate_limited | Too many requests. The Retry-After header says when to try again. |
Routes
The routes below are examples. The complete description of the API is published with it, as an OpenAPI document at /v1/openapi.json.
| Route | Purpose |
|---|---|
GET /v1/orgs/{org}/endpoints | List the endpoints of an organization. |
POST /v1/orgs/{org}/endpoints | Register an endpoint. It is created in DRAFT. |
GET /v1/orgs/{org}/endpoints/{id} | Read one endpoint. |
POST /v1/orgs/{org}/endpoints/{id}/verification | Start ownership verification for an endpoint. |
GET /v1/orgs/{org}/policies | List mitigation policies. |
GET /v1/orgs/{org}/telemetry?range=24h | Read telemetry for a range: 1h, 24h, 7d or 30d. |
GET /v1/orgs/{org}/incidents | List incidents. |
Examples
In these examples {org} is the identifier of your organization and {id} is the identifier of an endpoint. The credential is read from an environment variable.
List endpoints:
curl https://api.umbren.net/v1/orgs/{org}/endpoints \
-H "Authorization: Bearer $UMBREN_API_CREDENTIAL"Register an endpoint. The request body uses these fields:
| Field | Value |
|---|---|
name | The service name. |
category | generic_udp, generic_tcp, vpn, gaming or other. |
origin_ip | A single public IPv4 or IPv6 address. |
protocol | udp or tcp. |
port_start, port_end | The first and last port of the range. Use the same value twice for a single port. |
preferred_region | auto, or a region offered by a connected provider. |
connection_requirements | Free-text notes. |
protection_profile | standard, strict, wireguard or custom. |
curl -X POST https://api.umbren.net/v1/orgs/{org}/endpoints \
-H "Authorization: Bearer $UMBREN_API_CREDENTIAL" \
-H "Content-Type: application/json" \
-d '{
"name": "edge-tunnel-01",
"category": "vpn",
"origin_ip": "203.0.113.10",
"protocol": "udp",
"port_start": 51820,
"port_end": 51820,
"preferred_region": "auto",
"connection_requirements": "WireGuard-compatible tunnel endpoint.",
"protection_profile": "wireguard"
}'203.0.113.10 is a documentation address used here as a placeholder. Reserved ranges are rejected, so use your own public address.
Start agent verification for an endpoint:
curl -X POST https://api.umbren.net/v1/orgs/{org}/endpoints/{id}/verification \
-H "Authorization: Bearer $UMBREN_API_CREDENTIAL" \
-H "Content-Type: application/json" \
-d '{"method":"agent"}'Read the last 24 hours of telemetry:
curl "https://api.umbren.net/v1/orgs/{org}/telemetry?range=24h" \
-H "Authorization: Bearer $UMBREN_API_CREDENTIAL"Roles and permissions
Each member of an organization holds one role.
| Role | Access |
|---|---|
| Owner | Full control of the organization. |
| Admin | Members, infrastructure, policies, billing and settings. Cannot delete the organization or displace owners. |
| Engineer | Protected infrastructure, policies and notifications. May authorize activation. |
| Billing | Subscription, invoices and payment details. |
| Viewer | Read-only access to infrastructure, analytics and incidents. |
The data of each organization is isolated. A request for a resource that belongs to another organization returns 404, the same response as for a resource that does not exist.
Account security
- Email verification. An email address must be verified.
- Passwords. At least 12 characters.
- Two-factor authentication. Time-based one-time passwords (TOTP), with one-time recovery codes.
- Sessions. You can list your active sessions and revoke them.
- Audit log. Sensitive actions are recorded in an append-only audit log. Actions taken by UMBREN staff are recorded in it too.
Demo mode and simulated providers
UMBREN keeps real data and example data apart. Three things can look alike and are not the same.
- Awaiting telemetry. A real endpoint for which no telemetry has been reported yet. The dashboard says so and shows no placeholder traffic.
- Demo mode. A separate, clearly labelled mode that shows simulated data, so that you can see how the dashboard works. Nothing shown in demo mode describes your infrastructure.
- Simulated providers. In evaluation environments an endpoint may be staged on a simulated provider. Such an endpoint is labelled “simulated” everywhere it appears. It never counts as protected.
Getting help
For questions about onboarding, manual verification, capacity for your endpoints or an Enterprise agreement, contact us. If your question is about a failed API request, include the request_id from the error.