Raxx · internal docs

internal · gated

FreeScout configuration audit — 2026-06-05

Scope issue: #3280 Audit date: 2026-06-05 UTC Method: FreeScout REST API (credentials read from vault at /MooseQuest/freescout/ and /MooseQuest/cloudflare/) + live HTTP probe of tickets.raxx.app Parallel workflow: wf_f3757591-222 (email deliverability E2E) covers Postmark DKIM/SPF/DMARC; this audit cross-links rather than re-tests that scope.


Executive summary

Verdict: PARTIAL-GO for v1 launch — with one CRITICAL blocker that must be resolved before launch, and two HIGH gaps that should be resolved before real customer volume lands.

The core FreeScout machinery is working: three mailboxes exist, conversations route correctly via the API, the queue worker is functional, the Webhooks module is installed, tags exist, and the API is properly authenticated. The Operations mailbox is the most complete (it has live non-test conversation history). The Support mailbox exists and accepts inbound tickets via API but has test-only conversation history.

The blocker is the CF Access gate: the FreeScout login page at tickets.raxx.app/login is directly reachable from the public internet without a Cloudflare Access challenge. Any attacker can attempt credential brute-force or phishing attacks against the FreeScout admin panel. The runbook documents a root-domain CF Access policy, but live verification confirms it is not enforcing.

Secondary gaps: the privacy@raxx.app mailbox is missing (required for GDPR/CCPA DSR intake), custom fields for customer-tier/severity triage are not defined (only console_customer_url exists), no webhook is registered (the audit webhook for SC-A4 is configured in code but not provisioned in FreeScout), and the FreeScout TOTP secret is not stored in vault (meaning 2FA enrollment status is unknown and recovery codes are absent).


Per-mailbox completeness table

Mailbox 1 — Raxx Support (support@raxx.app) [ID: 1]

Check Result Note
Mailbox exists PASS Created 2026-05-04
Email address PASS support@raxx.app
From-name PASS "Raxx Support"
Conversation count INFO 16 total; all state=deleted (test-only history)
Has real customer conversations WARN All 16 conversations are state=deleted; none are published active customer tickets. 0 published conversations.
Custom fields on conversations PARTIAL Only console_customer_url (ID 1) — none of the required triage fields (tier, severity, category, surface, browser/OS)
Auto-reply text UNVERIFIABLE FreeScout API does not expose auto-reply configuration per project_freescout_api_limits; requires UI verification
Signature text UNVERIFIABLE API does not expose per-mailbox signature; requires UI verification
Business hours UNVERIFIABLE API does not expose business hours; requires UI verification
Aliases None found No alias conversations observed
Default conversation status INFO Inbound API tickets arrive as active; manually-created conversations arrive as pending
Permissions / user access INFO Admin (Kristerpher, ID 1) has full access; no CS rep users provisioned
Folders PASS All 8 standard folders present: Unassigned, Mine, Starred, Drafts, Assigned, Resolved, Deleted, Spam
Additional custom folders INFO Two extra folders present (IDs 25 "Received", 26 "Working") — non-standard

Mailbox 2 — Operations (ops@raxx.app) [ID: 2]

Check Result Note
Mailbox exists PASS Created 2026-05-05
Email address PASS ops@raxx.app
From-name PASS "Operations"
FREESCOUT_OPERATIONS_MAILBOX_ID in vault PASS Secret is SET in vault at /MooseQuest/freescout/
Auto-ticket routing PASS Conversation #4 ([auto:status] Nightly Security Scan) and #25 (outbound test) confirm API-created tickets route here
Tags on ops tickets INFO Tag auto:status (ID 1) and ops:incident (ID 2) exist; conversation #4 was created with auto:status tag
Has real operational tickets PASS Conversation #4 is a live ops ticket; #19 is a vendor thread (Heroku support)
Outbound email test PASS Conversation #25 ([Test] Outbound test e-mail from operations.) created today (2026-06-05) with body confirmed
Custom fields NONE Ops mailbox conversations carry no custom fields; acceptable for internal ops tracking
Folders PASS All 8 standard folders present

Mailbox 3 — Accounts (account-management@raxx.app) [ID: 3]

Check Result Note
Mailbox exists PASS Created 2026-05-11
Email address PASS account-management@raxx.app
From-name PASS "Accounts"
Conversation history INFO 2 total — both state=deleted test conversations
Custom fields NONE No custom fields on Accounts mailbox conversations
Folders PARTIAL Only 8 standard folders present; missing custom "Received" and "Working" folders that support mailbox has

Mailbox — privacy@raxx.app

Check Result Note
Mailbox exists FAIL Not present in FreeScout. The spec (issue #3280) requires a privacy@raxx.app mailbox for DSR/GDPR intake. Total mailbox count: 3 (not 4).

System-level completeness table

Check Result Note
Custom fields — console_customer_url PASS Field ID 1, name console_customer_url, present on support mailbox conversations
Custom fields — Customer Tier FAIL Not defined. No customer_tier / plan field exists.
Custom fields — Account ID (Raptor user_id) FAIL Not defined. No account_id field exists.
Custom fields — Ticket Category FAIL Not defined. No category / ticket_category field exists.
Custom fields — Severity PARTIAL incident_severity field referenced in freescout-status-fields.md and create-status-fields.sh for status.raxx.app integration; per API probe, /api/custom-fields returns HTTP 405 (endpoint not exposed by installed API module version). Cannot confirm if incident_severity exists via API; requires UI verification.
Custom fields — Component Tag PARTIAL Same caveat as above — cannot confirm via API
Custom fields — Surface / Browser-OS FAIL No evidence of these fields in any conversation customFields array
Tags PARTIAL 4 tags: auto:status, ops:incident, testing, received. Missing: billing, auth, trading, bug, feature-request — common CS triage tags not defined
Workflow rules / automations FAIL /api/workflows returns HTTP 405 (Workflows module either not installed or API endpoint not exposed). 0 automations verifiable.
Users PASS 2 users: Kristerpher (admin, timezone=UTC), Workflow (user, fsworkflow@example.org — automation account)
Admin user timezone PASS UTC
Admin user name PASS "Kristerpher" (correct — not "Kris")
Slack integration UNVERIFIABLE No API endpoint exposed; requires UI verification at Settings > Integrations
OAuth (Google) integration UNVERIFIABLE GOOGLE_OAUTH_CLIENT_ID and GOOGLE_OAUTH_CLIENT_SECRET are NOT_FOUND in vault at /MooseQuest/freescout/. Google OAuth module may not be configured.
API & Webhooks — registered webhooks FAIL /api/webhooks returns HTTP 200 with empty list. Zero webhooks registered. The SC-A4 audit webhook (runbook: freescout-webhook-setup.md) is not provisioned.
API key rotation policy UNVERIFIABLE No documented rotation schedule; key is valid and in vault but no expiry or rotation cadence defined
General settings — company name PARTIAL Title tag on login page is <title>FreeScout</title> not <title>Raxx Support</title>. Logo banner is 184x36px PNG at /img/banner.png (2036 bytes — too small to confirm Raxx wordmark); may be default FreeScout banner.
"Powered by FreeScout" footer PARTIAL Not detected in login page body. RaxxTheme CSS (/modules/raxxtheme/css/theme.css, HTTP 200, 12452 bytes) confirms Powered by suppression is likely applied. Cannot confirm from API alone.
Email signature — global vs per-mailbox UNVERIFIABLE API does not expose signature configuration
RaxxTheme module active PARTIAL CSS file accessible at /modules/raxxtheme/css/theme.css with correct CE palette tokens (#5B8C5A moss, #0B0F14 near-black). However, the login page body class is locale-en user-is-guest — it does NOT include login class. The body.login CSS selector in theme.css never matches. CE dark theme is NOT applied to the login page despite being deployed.
TOTP 2FA on admin account UNKNOWN FREESCOUT_TOTP_RECOVERY_CODES is NOT_FOUND in vault. Either TOTP was never enrolled (meaning admin account has no 2FA behind the CF Access gate) or enrollment happened but recovery codes were not stored. Per runbook freescout.md §Admin account security, recovery codes must be stored in vault to close this item.
CF Access — root domain gate CRITICAL FAIL See below
CF Access — /api path gate PASS /api/mailboxes returns HTTP 403 without CF Access headers (service token required for API path)
FreeScout API auth PASS API returns HTTP 401/403 without X-FreeScout-API-Key header
FREESCOUT_AUDIT_WEBHOOK_SECRET in vault FAIL NOT_FOUND at /MooseQuest/freescout/FREESCOUT_AUDIT_WEBHOOK_SECRET. SC-A4 pre-flight requirement not met.

Routing + deliverability cross-checks

Check Result Note
Postmark outbound DKIM/SPF/DMARC DEFERRED Covered by parallel workflow wf_f3757591-222. Cross-link findings to that report.
Postmark inbound routing UNVERIFIABLE FreeScout API does not expose SMTP/webhook inbound configuration. Requires UI verification and a live test email send to each mailbox address.
Reply-To threading INFO Conversation #25 shows correct threading (operator reply linked to conversation). Reply-To header configuration not verifiable via API alone.
CF Access — /api path PASS Service token gate confirmed working (HTTP 403 without headers)
CF Access — root domain CRITICAL FAIL See gap #1 below

Gaps ranked by severity

CRITICAL

GAP-1: CF Access root domain gate is not enforcing


HIGH

GAP-2: privacy@raxx.app mailbox missing

GAP-3: TOTP 2FA enrollment status unknown; recovery codes not in vault

GAP-4: SC-A4 audit webhook not provisioned in FreeScout


MEDIUM

GAP-5: Customer-triage custom fields not defined

GAP-6: RaxxTheme body.login selector mismatch

GAP-7: CS triage tags not defined

GAP-8: Google OAuth not configured


LOW

GAP-9: Login page title is "FreeScout" not "Raxx Support"

GAP-10: banner.png is 184x36px (may be default FreeScout logo, not Raxx wordmark)

GAP-11: API key rotation policy not documented

GAP-12: Workflow user (ID 2) uses placeholder email

GAP-13: Accounts mailbox missing "Received" and "Working" custom folders


Items this audit fixed via API (feedback_fix_dont_file)

None. All identified gaps either require UI-only operator actions (per project_freescout_api_limits), require feature-developer code changes (GAP-6 — RaxxTheme body class), or require an operator decision before an automated fix is appropriate (GAP-7 — tag taxonomy).

The following endpoints returned HTTP 405 (not supported by the installed API module version), blocking any API-level fixes: - GET /api/custom-fields (405) — would have allowed adding missing triage fields - GET /api/workflows (405) — would have allowed checking automation rules - GET /api/mailboxes/{id} (405) — would have allowed per-mailbox detail (signature, hours, auto-reply)


Gap Severity Action Who
GAP-1: CF Access root gate not enforcing CRITICAL Re-apply CF Access application to tickets.raxx.app root. Verify Terraform state in terraform/freescout/. Test login page requires CF Access OTP challenge. Operator (Terraform)
GAP-2: privacy@raxx.app missing HIGH Create mailbox in FreeScout UI. Configure Postmark inbound route for privacy@raxx.app. Operator (UI)
GAP-3: TOTP unknown, recovery codes absent HIGH Log in to FreeScout, verify/enroll TOTP, store recovery codes in vault. Operator (personal)
GAP-4: SC-A4 webhook not provisioned HIGH Generate + store FREESCOUT_AUDIT_WEBHOOK_SECRET; register webhook in FreeScout UI; enable flag per freescout-webhook-setup.md. Operator (UI + vault)
GAP-5: Triage custom fields missing MEDIUM Create fields via FreeScout UI or script after deciding taxonomy. Operator + feature-dev
GAP-6: RaxxTheme body.login mismatch MEDIUM Fix ServiceProvider to inject login body class, or update CSS selector to match FreeScout's actual class. Feature-developer
GAP-7: CS triage tags absent MEDIUM Decide tag taxonomy; file card for create-triage-tags.sh script. Operator decision + feature-dev
GAP-8: Google OAuth not configured MEDIUM Follow freescout-google-oauth.md; store vault secrets. Operator (UI + vault)
GAP-9: Title "FreeScout" LOW Admin > Settings > General > Company Name = "Raxx Support" Operator (UI)
GAP-10: Default banner.png LOW SSH to Lightsail; replace with Raxx wordmark PNG Operator (SSH)
GAP-11: API key rotation undocumented LOW Add rotation reminder or card Future card
GAP-12: Workflow user placeholder email LOW Update user email in FreeScout Admin > Users Operator (UI)
GAP-13: Accounts missing custom folders LOW Investigate if "Received"/"Working" folders are intentional on Support; if yes, add to Accounts Operator (UI)

API-not-readable surfaces (require UI verification by operator)

The following items cannot be confirmed via the FreeScout REST API (per project_freescout_api_limits). Kristerpher must verify manually in the FreeScout admin UI:

  1. Per-mailbox signatures — Settings > Mailboxes > [each mailbox] > Signature. Confirm Raxx voice, no forward-looking framing, no vendor attribution, no freescout.net URLs.
  2. Per-mailbox auto-reply — Settings > Mailboxes > [each mailbox] > Auto Reply. Confirm: is it on or off? If on, review content for Raxx voice + reasonable response-time framing.
  3. Global SMTP settings — Settings > General > Sending Email. Confirm smtp.postmarkapp.com:587, support@raxx.app from-address, Raxx Support from-name. The POSTMARK_SERVER_API_KEY is confirmed SET in vault.
  4. Slack integration — Settings > Integrations > Slack (if module installed). What channel is configured?
  5. Customization module settings — Settings > Customization. Footer, primary color, APP_NAME per the post-deploy checklist.
  6. Custom fields list — Settings > Custom Fields. Confirm component_tag, public_status, incident_severity (from status.raxx.app integration) are present. Confirm console_customer_url is the only field on Support.
  7. Workflows / automations — Settings > Workflows. Confirm zero automations or document existing ones.
  8. Modules page — Settings > Modules. Confirm all 10 paid modules are Active. Specifically: API & Webhooks, Custom Fields, Workflows, Customization, Slack, OAuth, Custom Folders, Saved Replies, Reports, Tags.
  9. "Powered by FreeScout" footer — Settings > General > Customization. Should be disabled.
  10. CF Access on login page — navigate to tickets.raxx.app/login in a private browser window (no session). Should see CF Access email OTP challenge, NOT the FreeScout login form directly. Currently this challenge does NOT appear (GAP-1 CRITICAL).

Observed state that indicates healthy configuration


Operator-action cards filed by this audit

Cards filed as part of this audit (all blocked:operator-action):


Audit performed by qa-agent. Vault reads via Infisical universal auth. All secret values read-only; no vault writes performed. No FreeScout data modified.