Architecture

System Context

The Edge service sits at the Cloudflare layer between external clients (mobile app, web, backoffice) and FloatMe’s internal platform. All inbound traffic is protected by Cloudflare’s WAF before reaching any worker. Workers proxy requests to Auth0 for identity operations, call internal services over IAM-signed HTTP, and integrate with third-party platforms for fraud detection, analytics, and SMS delivery.

system context edge

Inbound Traffic

Domain Worker Purpose

auth.floatme.io

Auth (prod-auth)

Auth0 proxy for mobile app: login, signup, MFA, social auth, session tokens, user info, and analytics tracking.

auth.test.floatme.io

Auth (test-auth)

Same worker, test environment Auth0 tenant. Castle blocking disabled.

sms.floatme.io

SMS (prod-sms)

Text-Me-The-App endpoint called from floatme.com and paid ad campaigns.

sms.test.floatme.io

SMS (test-sms)

Same worker, test environment.

links.floatme.io

Links (prod-links)

Deeplink redirect and .well-known file serving (AASA, assetlinks.json).

links.test.floatme.io

Links (test-links)

Same worker, test environment.

auth.backoffice.floatme.io

Backoffice Auth (prod-backoffice-auth)

Auth0 proxy for the internal admin console (password-realm grant against the floatme-backoffice Auth0 tenant).

auth.backoffice.test.floatme.io

Backoffice Auth (test-backoffice-auth)

Same worker, test tenant.

Outbound Traffic

Worker Destination Description

Auth

Auth0 (floatme.auth0.com)

All OAuth2/OIDC operations: token issuance, user creation, password management, MFA enrollment, social authentication, management API calls.

Auth

User Service

IAM-signed POST to /users-by-email to check user status before login; POST to unblock paused users.

Auth

Castle (api.castle.io)

Pre-login and pre-signup risk scoring. Sends device fingerprint and user context; blocks or challenges on DENY/CHALLENGE policy response.

Auth

Segment

floatmetric-track events forwarded to the FloatMe metrics endpoint, which fans out to Segment.

Auth

Datadog

Structured logs shipped via DatadogLogger at request completion.

Backoffice Auth

Auth0 (floatme-backoffice.us.auth0.com)

Password-realm token request on behalf of backoffice console users.

Backoffice Auth

Datadog

Structured logs.

SMS

Twilio

Sends SMS messages via the Twilio Messaging API using a pre-configured messaging service SID.

SMS

Datadog

Structured logs.

Links

Datadog

Structured logs.

External Services

Auth0

Auth0 is the identity provider for all FloatMe authentication. The auth worker proxies client requests to Auth0’s Authentication API and Management API, keeping credentials server-side and enforcing FloatMe-specific logic (Castle checks, user status validation) before token issuance.

Usage Detail

Authentication API

Token issuance, user creation, password management, MFA enrollment and challenge/submit, social authentication.

Management API

Reading and updating user metadata (e.g. unblocking paused users). Uses a separate management client credential.

Tenants

floatme.auth0.com (prod), floatme-test.us.auth0.com (test) for mobile; floatme-backoffice.us.auth0.com (prod), floatme-backoffice-test.us.auth0.com (test) for backoffice.

Workers

Auth worker (primary), Backoffice Auth worker.

Table 1. Auth Worker Secrets
Secret Name Purpose

AUTH0_CLIENT_SECRET

Client secret for the mobile Auth0 application.

AUTH0_CONNECTION

Database connection name (e.g. Username-Password-Authentication).

AUTH0_AUTHENTICATION_AUDIENCE

Audience for access tokens.

AUTH0_AUTHENTICATION_ISSUER

Expected issuer for JWT validation.

AUTH0_MFA_AUDIENCE

Audience for MFA-scoped tokens.

AUTH0_MANAGEMENT_CLIENT_ID

Client ID for the Management API client.

AUTH0_MANAGEMENT_CLIENT_SECRET

Client secret for the Management API client.

AUTH0_MANAGEMENT_AUDIENCE

Audience for Management API tokens.

Table 2. Backoffice Auth Worker Secrets
Secret Name Purpose

AUTH0_CLIENT_SECRET

Client secret for the backoffice Auth0 application.

Castle

Castle provides device-based fraud and abuse detection. The auth worker calls Castle before login and signup operations, sending a fingerprint token extracted from the request. If Castle returns DENY and ENABLE_CASTLE_BLOCKING is true (prod only), the request is rejected before reaching Auth0. A CHALLENGE result is logged but does not block in the current implementation.

Usage Detail

Pre-login check

handlePreLoginRequest — sends email + fingerprint; blocks if policy is DENY.

Pre-signup check

handlePreSignupRequest — sends email + fingerprint; blocks if policy is DENY.

Post-login signal

handleSuccessfulLoginRequest / handleFailedLoginRequest — reports outcome back to Castle for model feedback.

Workers

Auth worker only.

Table 3. Castle Secrets
Secret Name Purpose

CASTLE_CLIENT_SECRET

API key for authenticating requests to api.castle.io.

Segment

Analytics events are forwarded through the FloatMe metrics service (an internal API Gateway endpoint) rather than calling Segment directly. The floatmetric-track handler in the auth worker receives tracking payloads from the mobile app and forwards them via IAM-signed request.

Usage Detail

floatmetric-track

Proxies mobile analytics events to the FloatMe metrics endpoint (FLOATME_METRICS_URL), which fans out to Segment.

Workers

Auth worker only.

SEGMENT_WRITE_KEY and SEGMENT_BASE_URL are defined in the shared Env interface for potential direct Segment use but the current auth worker routes through the metrics endpoint.

Twilio

The SMS worker uses Twilio to deliver the Text-Me-The-App message. Phone number validation uses the phone library to reject non-US numbers before the Twilio API is called. The worker enforces CORS origin allowlisting to prevent abuse from unauthorized domains.

Usage Detail

SMS delivery

Sends a campaign-specific message via the Twilio Messaging API (SMS_TMTA_TWILIO_MESSAGING_SID).

Workers

SMS worker only.

Table 4. SMS Worker Secrets
Secret Name Purpose

TWILIO_AUTH_TOKEN

Auth token for Twilio account TWILIO_ACCOUNT_SID.

Datadog

All four workers emit structured logs to Datadog via DatadogLogger. Logs are queued in-memory during the request and flushed via DatadogLogger.sendQueuedLogs() in the worker’s ctx.waitUntil() callback, ensuring log delivery does not block the response.

Usage Detail

Log shipping

All structured log events (info, warn, error) are batched and POSTed to https://http-intake.logs.datadoghq.com/api/v2/logs.

Service tagging

Each worker registers with a service name in the format {WORKER_ENV}-{handlerName} (e.g. prod-auth).

Workers

All workers (Auth, Backoffice Auth, SMS, Links).

Table 5. Datadog Secrets (all workers)
Secret Name Purpose

DATADOG_API_KEY

API key for authenticating log ingestion requests.

Cloudflare KV

Cloudflare KV is not currently used by any active worker. The shared Env interface and wrangler configurations do not define KV namespace bindings. This section is reserved for future use if caching or state storage is added.

Request Handling Pattern

All workers share a common set of helper modules located in cloudflare/helpers/.

request-handler.ts

The central dispatch wrapper. Every worker’s fetch() handler calls handleRequest(logger, request, env, handlerFn). It executes the given handler function and catches any unhandled exceptions, returning a 500 Internal Server Error response and logging the error to Datadog. This ensures no exception can leak an unformatted error to the client.

export default async function handleRequest(
  logger: DatadogLogger,
  request: Request,
  env: Env,
  handler: Function,
): Promise<any> {
  try {
    return handler(logger, request, env);
  } catch (err) {
    logger.error(err, 'unexpected error handling the request');
    return createHttpResponse('Internal Server Error', StatusCodes.INTERNAL_SERVER_ERROR);
  }
}

http-error.ts

Defines HttpError, a typed error class that carries an HTTP status code and optional structured details payload. Handlers throw HttpError instances for expected failure cases (e.g. invalid input, upstream Auth0 errors). request-handler.ts catches any remaining untyped exceptions as a safety net.

http-response.ts

A thin wrapper around the Cloudflare Workers Response constructor. createHttpResponse(body, status) sets content-type: application/json and serialises non-string bodies via JSON.stringify. All handlers return responses through this function for consistent formatting.

datadog-logger.ts

A singleton-per-service logger class. DatadogLogger.getDatadogLogger(env, serviceName) returns a cached instance keyed on {WORKER_ENV}-{serviceName}. Logs are queued in-memory with info(), warn(), and error() methods and flushed in bulk to the Datadog HTTP intake API at the end of each request via DatadogLogger.sendQueuedLogs(env). The withValues() method attaches persistent key-value pairs (e.g. request context) to all subsequent log entries from the same instance.

Secrets Management

How Secrets Are Uploaded

Each worker has a secrets.sh script in its directory (e.g. cloudflare/workers/auth/secrets.sh). The script reads secrets from shell environment variables and pushes them to Cloudflare using wrangler secret put:

echo $AUTH0_APP_CLIENT_SECRET | wrangler secret put AUTH0_CLIENT_SECRET --env $FLOATME_ENVIRONMENT
echo $CASTLE_CLIENT_SECRET    | wrangler secret put CASTLE_CLIENT_SECRET --env $FLOATME_ENVIRONMENT
echo $DATADOG_API_KEY         | wrangler secret put DATADOG_API_KEY      --env $FLOATME_ENVIRONMENT
# ... additional secrets

$FLOATME_ENVIRONMENT must be set to prod or test before running. The top-level Makefile provides make secrets targets that invoke the appropriate secrets.sh scripts.

How Secrets Are Injected at Runtime

Cloudflare injects secrets as environment bindings at worker startup. They are accessible on the env object passed to each worker’s fetch(request, env, ctx) handler and typed in cloudflare/helpers/env.ts. Non-secret configuration (base URLs, feature flags, SIDs) is declared in wrangler.toml under [env.prod.vars] and [env.test.vars] — these are plain environment variables visible in the wrangler config and suitable for non-sensitive values only.