Iwf Guide

Iwf Guide

Security and Deployment

Production security is explicit. Iwf provides secure config checks, security header helpers, and RLS request-context utilities, but the app still owns secrets, TLS termination, database roles, and deployment infrastructure.

1. Production Config

Use:

config : AppConfig
config =
  productionConfig sessionSecret databaseUrl

Then validate before booting:

case validateProductionConfig config of
  Right _ => pure ()
  Left warnings => traverse_ putStrLn warnings

validateProductionConfig checks:

  • mode is Production
  • session secret is not the default
  • session cookies are secure
  • session cookies are HTTP-only

2. Security Headers

Use the default production security header policy at the deployment edge or in the lower-level server boundary when an app needs to wrap raw handlers.

headers : SecurityHeaders
headers =
  defaultProductionSecurityHeaders

Default headers include:

  • Strict-Transport-Security
  • Content-Security-Policy
  • Referrer-Policy
  • X-Frame-Options
  • X-Content-Type-Options
  • Permissions-Policy

Send HSTS only when the app is served through HTTPS.

Use custom headers when needed:

headers : SecurityHeaders
headers =
  { contentSecurityPolicy := Just "default-src 'self'; img-src 'self' data:" }
    defaultProductionSecurityHeaders

3. Deployment Validation

Validate app config and headers together:

case validateDeployment config defaultProductionSecurityHeaders of
  Right _ => start
  Left warnings => fail warnings

deploymentWarnings returns all warnings without short-circuiting.

4. Session Fixation

Iwf stores a framework session id in the signed session under _session_id. The controller lifecycle ensures one exists before handlers render a response. The controller login and logout helpers create a new signed session, rotate _session_id, and rotate the session-backed CSRF token. This means an anonymous session cookie is not reused unchanged after authentication, and a logged-out cookie cannot keep the old authenticated session id.

5. Row-Level Security

PostgreSQL RLS is schema-owned. Iwf parses RLS metadata and provides helpers for request-local context:

  • authenticatedRlsContext
  • authUserRlsContext
  • anonymousRlsContext
  • rlsTransaction
  • withRlsTransaction
  • rlsEnabledTables
  • rlsPoliciesForTable
  • rlsSchemaRequiresRequestContext

RLS setup prepends SET LOCAL ROLE and app.current_user_id before application SQL inside a transaction.

6. Deployment Checklist

Before shipping:

  • use Production mode
  • use a real session secret
  • use secure HTTP-only session cookies
  • rely on loginUserInContext/logoutUserInContext or rotate session ids explicitly around custom auth flows
  • serve through HTTPS before HSTS
  • run the app's schema, migration, and typegen check workflow
  • run framework and app tests
  • confirm migrations and Application/Schema.sql match
  • confirm generated schema files are build artifacts
  • mount Swagger docs only where intended
  • protect internal dashboards with auth
  • configure upload storage outside ephemeral app disks unless local storage is deliberate

Next

Read Testing and Debugging.