Submit Feedback
Submit feedback about the Umbra platform via email.
Endpoint
Authentication
Requires a valid form token obtained from the /api/form-token endpoint.
Rate Limiting
3 requests per 2 minutes per IP address. Returns 429 Too Many Requests with a Retry-After header when exceeded.
Security Requirements
- Must be same-origin request (checked via
Origin header)
- Must have
Content-Type: application/json
- Must include valid form token (10-minute expiry)
- Honeypot field (
checkpoint) must be empty
Request Parameters
Email address for follow-up (max 200 characters). Must be a valid email format.
Name of the person submitting feedback (max 200 characters)
Feedback message (max 2000 characters)
Source of the feedback (e.g., “chat”, “homepage”, “docs”). Defaults to “unspecified”. Max 140 characters.
HMAC-signed form token from /api/form-token
Request Body
{
"email": "[email protected]",
"name": "Alice Johnson",
"message": "The attestation verification process is very smooth. Would love to see support for SEV-SNP in addition to TDX.",
"source": "chat",
"form_token": "a1b2c3d4e5f6.1709654400.8f3a2b1c4d5e6f7890123456789abcdef0123456",
"checkpoint": ""
}
Response
Whether the feedback was submitted successfully
Error Responses
400 Bad Request
- Missing or invalid email
- Missing or empty message
- Missing or expired form token
- Honeypot field not empty
403 Forbidden
- Cross-origin request blocked
- Missing or invalid
Content-Type header
422 Unprocessable Entity
- Email format validation failed
429 Too Many Requests
- Rate limit exceeded (includes
Retry-After header with seconds to wait)
500 Internal Server Error
- Feedback inbox not configured (
RESEND_TO_EMAIL_FEEDBACK env var missing)
- Email delivery failed
Example
# First, get a form token
TOKEN=$(curl https://umbra.concrete-security.com/api/form-token | jq -r '.token')
# Then submit feedback
curl -X POST https://umbra.concrete-security.com/api/feedback \
-H "Content-Type: application/json" \
-H "Origin: https://umbra.concrete-security.com" \
-d "{
\"email\": \"[email protected]\",
\"name\": \"Alice Johnson\",
\"message\": \"Great platform! Love the TEE integration.\",
\"source\": \"chat\",
\"form_token\": \"$TOKEN\",
\"checkpoint\": \"\"
}"
Success Response
Error Response
{
"error": "Feedback cannot be empty."
}
Email Delivery
Feedback is delivered via Resend to the address configured in the RESEND_TO_EMAIL_FEEDBACK environment variable. The email includes:
- Source of feedback
- Submitter’s name and email
- Message content (HTML formatted with proper escaping)
- Subject line:
Umbra beta feedback ({source})
HTML content is escaped to prevent injection attacks using a custom escapeHtml function.
Validation Rules
- Email: Required, max 200 characters, must match basic email regex (
/^[^\s@]+@[^\s@]+\.[^\s@]+$/), converted to lowercase
- Name: Optional, max 200 characters, trimmed
- Message: Required, max 2000 characters, trimmed
- Source: Optional, max 140 characters, defaults to “unspecified”
- Form Token: Required, must be valid HMAC signature and not expired (10-minute TTL)
- Checkpoint: Must be empty (honeypot field)
Implementation Details
The endpoint implements multiple security layers:
- Same-origin enforcement via header validation
- Rate limiting per IP address (3 req/2min)
- HMAC-signed form tokens with expiry
- Honeypot field for bot detection
- Input sanitization and HTML escaping
- Email delivery via Resend API
Source: frontend/app/api/feedback/route.ts