Sign In
Security & Privacy

Security is not
an add-on.
It's the foundation.

dWell-KC manages protected information, sensitive financial records, and case data for vulnerable people. Every layer of the platform — from the database to the browser — is built with security and privacy as a first principle.

Encrypted in Transit & at Rest
Role-Based Access Control
Complete Audit Trail
SSNs Never Exported
Org-Scoped Data Isolation
PHI & Sensitive Data

Sensitive data protected
at every layer.

dWell-KC handles Protected Health Information (PHI) including Social Security Numbers, health and disability records, and income data. The most sensitive fields are encrypted one by one, every protected field is limited by role and organization, and SSNs are left out of every data export.

  • Cross-agency identity matching uses salted SHA-256 SSN digests, never the SSN itself
  • SSNs, diagnoses and medical notes encrypted individually (AES-256-GCM), including SSNs entered on intake forms
  • Database encrypted at rest by the hosting provider; connections require TLS
  • SSN, diagnosis, medical notes, disabilities and DV detail limited to org admins and the client's case managers
  • PHI fields masked in logs and error reports
  • Encryption keys, hashing salt and other secrets kept outside the source code

How SSNs are handled

1 Staff or the client enter the SSN over HTTPS, on the client's record or an intake form
2 Only the owning org's admins and the client's case managers can view it
3 The SSN is stored encrypted (AES-256-GCM), plus a salted SHA-256 digest on the shared identity record
4 Duplicate checks compare keyed digests, so other agencies never see the SSN; two records with the same SSN are flagged as a hard duplicate and both agencies' admins are notified
5 SSNs are filtered from logs, masked to the last four digits on screen, and left out of every data export

Encryption at rest

SSNs, diagnoses and medical notes on client and family records are encrypted individually with AES-256-GCM (Lockbox), so a database dump or backup shows only ciphertext. Their change history keeps only the ciphertext too. The rest of the database and its backups are encrypted at rest by our hosting provider, and the application only connects to it over TLS.

Duplicate-client checks match SSNs through a keyed blind index (BlindIndex), so lookups never decrypt stored values.

Authentication & Authorization

The right people see the right data.

Access is never assumed. Every request is authenticated and every action is authorized based on the user's role and organizational context before a single database row is touched.

Authentication

Powered by Devise — an industry-standard authentication framework used by thousands of production applications. All routes require authentication by default. Staff get access to an organization only through that organization's administrators, usually by a secure email invitation.

  • Passwords of 12–128 characters, stored only as bcrypt hashes
  • Account locks after 5 failed sign-ins, until an emailed unlock link or an hour passes
  • Automatic sign-out after inactivity, set by each organization (5 minutes to 8 hours) with an optional region-wide maximum; a one-minute warning, then every open tab signs out
  • Staff of HIPAA covered entities must accept a versioned HIPAA acknowledgment before they can make changes
  • Secure invitations (Devise Invitable) and session cookies
Role-Based Authorization

Role-based access control enforces what each user can do. Roles are scoped per organization — a user can be an admin at one agency and a case manager at another. Abilities are evaluated server-side on every request; there is no client-side gate to bypass.

super_admin admin case_manager accountant prop. manager maintenance medical client
Organizational Isolation

Every query is scoped to the current organization. Beyond a client's basic identity, another organization's data is never accessible unless an explicit access grant exists or a record's Visibility level includes you. Parent organizations can manage their child orgs.

  • All queries scoped to current org at the controller layer
  • Parent/child org hierarchy with explicit impersonation controls
  • Sharing a client's record requires a ClientAccessGrant with the grantor's recorded certification
  • Victim service providers and HIPAA organizations appear to others only as "Protected Agency"
  • Property management orgs see only their own portfolio

Defense in depth — not just one gate

Authorization is checked at multiple layers: the request authentication filter, the role-based ability check, and the scoped database query. A misconfigured route cannot expose data from another org because the query itself will return zero rows for an unauthorized scope.

Audit Trail

Every change.
Every actor.
Every timestamp.

PaperTrail audit logging is active on all major models in dWell-KC. Every create, update, and destroy records the exact change, the user who made it, and the timestamp — automatically, with no extra developer effort required.

  • Complete change history for clients, enrollments, documents, and more
  • Every change attributed to the authenticated user who made it
  • Each change is linked to the access-log entry for the request that made it
  • History keeps only the ciphertext of encrypted fields, never the plaintext
  • Supports HUD audit requirements without a separate compliance workflow

Models with full PaperTrail audit logging

TenantProfile Identity ProjectEnrollment PipelineEnrollment ClientCase Goal Milestone Tenancy LedgerEntry OrganizationDocument VisitObservation FormResponse ShelterCheckIn

DataSnapshot — locked enrollment records

HMIS enrollment data is frozen into a DataSnapshot at entry and exit, automatically or on the schedule set in Region Settings. Each snapshot locks a set number of days after entry or exit (by default, 3 days after exit), enforced by a daily job in the region's time zone — preserving the exact state of the record for HUD reporting and audit purposes.

Email audit logging

Every outbound email is BCC'd to an internal EmailLog record. Delivery, open, and bounce events are captured via webhook so there is a permanent record of all system communications to users.

Access log — logins & page views

Every sign-in and every page a signed-in user visits is recorded to an internal AccessLog — user, organization context, path, IP address, and timestamp — reviewable by super-administrators for security investigation and HIPAA audit-control purposes.

Form & MVC Security

Input is never trusted.
Every request is verified.

Security controls applied to every request

1
CSRF Protection
Authenticity tokens on every non-GET form. Cross-site request forgery attacks cannot forge state-changing requests.
2
Authentication Gate
before_action :authenticate_user! on every controller. Public pages are explicitly allowlisted — everything else requires a valid session.
3
Ability Authorization
CanCanCan evaluates the current user's role and org context before any controller action executes. Unauthorized requests raise a 403 — not a silent empty result.
4
Strong Parameters
Every controller explicitly allowlists permitted params. Arbitrary fields cannot be mass-assigned — even if a form is manipulated client-side.
5
Org-Scoped Query
ActiveRecord scopes enforce organizational boundaries at the query level. A forged ID in a URL cannot access another org's data — the query returns empty.

Additional protections

  • XSS — Auto-escapes all output by default; raw HTML only via explicit `raw()` calls, reviewed case-by-case
  • SQL injection — values are bound or quoted by ActiveRecord; user input is never inserted into SQL raw
  • File uploads via ActiveStorage with content-type validation; direct-upload URLs are signed and short-lived
  • Subresource Integrity — every pinned CDN script and stylesheet carries a sha384 hash, so the browser refuses a file that has been altered
  • Website analytics load only on public pages — never once you sign in, or on links that can show client information
  • Intake forms use secret token URLs (Tokenizable concern) — no authentication required, but access requires a valid token
  • Tenant portal access gated by Devise session; tenants can only view their own profile and communications
  • Admin impersonation of child orgs is session-scoped and logged — actions taken under impersonation are attributed to the acting admin
  • Password reset tokens are single-use and expire after 6 hours (Devise default)
Access Control Policies

Shared only when
explicitly allowed.

Multi-agency coordination requires controlled sharing — not open access. dWell-KC's Visibility Permissions and the ClientAccessGrant model give staff simple, precise control over exactly what gets shared and with whom.

  • Every note, report, case, visit, document, observation and ledger entry carries one visibility level
  • Eight fixed levels from Private to Me up to Public, plus Invite Only for chosen teams, people and partner organizations
  • Levels only ever narrow access — never widen it past the client's own sharing
  • New records default to Internal — visible only inside your organization
  • ClientAccessGrant: explicit consent-based sharing with a specific agency — read-only profile, never Protected Info
  • Access grants revocable at any time — removed instantly across all systems
  • Victim service provider clients are left out of other agencies' HUD reports and Data Center

Visibility Permissions — one level per record

  1. Private to Me — Only you.
  2. Internal Admin — You and your organization's admins.
  3. Internal — Everyone in your organization.
  4. Agency Org Network — Your organization plus the agencies in its network.
  5. All Org Network — Your organization plus every organization in its network.
  6. All Agency Organizations — Every agency organization on dWell.
  7. All Organizations — Staff of every organization on dWell.
  8. Public — No visibility restriction.
  9. Invite Only — You plus the teams, people and organizations you pick.

Narrowest to widest. "Network" means the organization's parent, child and sibling organizations, the organizations it shares clients with, and the organizations of people on its teams. Only the creator and the organization's admins can edit or delete a restricted record.

Enforced everywhere the record appears

A restricted record is checked on its own page and also left out of lists, activity feeds, dashboard lists, pickers and search results for anyone outside its level. Notifications about it go only to people who can see it, and an observation's photos and notes are never copied into a report that more people can read.

ClientAccessGrant — consent-based cross-agency sharing

When a client needs services from multiple agencies, their primary agency creates a ClientAccessGrant to share the profile with a second organization. A grant records the grantor's certifications — HIPAA always, plus the ROI wording when the agency's Shared Access settings require an ROI on file — and it is time-stamped and revocable. A pipeline's Access Grant stage can make the grant: an admin certifies the stage once, the grant waits until the agency's requirements are on file, runs Full Access for one year, and names the pipeline and certifier. Without a grant, another agency can look up only a client's basic identity — name, aliases, contact details, current housing and agency contact — never case notes, HUD data or protected information.

  • With a grant, the partner sees the client page and a read-only profile; notes, reports and cases still follow their Visibility level.
  • HUD Hub opens for the partner only when the client is enrolled in one of its own projects — and shows only those enrollments.
  • Protected Info (SSN, diagnosis, disabilities, DV details) and identity documents are never shared, and only the primary agency can change them.

Victim service providers (VAWA)

Domestic violence and other victim service providers can flag their organization as a VSP. Other organizations then see it only as "Protected Agency" — in client records, chats, referrals, the ledger and notifications — and its staff names are hidden in shared chats. Its clients are left out of other agencies' HUD reports, the Data Center and the Data Explorer, and with the region's Full VSP Exclusion setting, out of client search too.

Infrastructure & Transport

Secure from the wire
to the database.

Security doesn't stop at the application layer. Transport encryption, payment security, and background job isolation are all first-class concerns.

HTTPS Everywhere

TLS enforced on all connections. Plain HTTP requests are automatically redirected to HTTPS. HSTS headers instruct browsers to never connect over plaintext.

PCI-Compliant Payments

Rent payments and CoC transfers run through Stripe Connect. Card data never touches dWell-KC servers. Stripe handles PCI DSS compliance; dWell-KC stores only payment intents and receipts.

PostgreSQL, Encrypted at Rest

PostgreSQL on encrypted storage, reached only over TLS, with SSN, diagnosis and medical notes columns encrypted by the application. Encryption keys and the SSN hashing salt are kept in the environment, never in source code.

Background Jobs (Sidekiq)

Async jobs (geocoding, pipeline auto-advance, APR generation) run in isolated Sidekiq workers backed by Redis. Jobs carry only IDs — no PHI is serialized into the queue.

File Uploads (ActiveStorage)

Documents, photos, and attachments are stored via ActiveStorage with content-type validation, in private cloud storage. Files are reached only through unguessable signed links shown on pages you're authorized to see, and the storage links behind them expire within minutes.

Real-Time Chat (ActionCable)

WebSocket connections authenticated via the same Devise session as the HTTP layer. Chat channels are scoped to their ChatMember list — subscription to a channel requires explicit membership, verified server-side.

Email Security (Resend)

Outbound email via Resend with SPF/DKIM/DMARC configured to prevent spoofing. Every sent email is BCC'd to an internal EmailLog. Delivery, open, and bounce events are tracked via signed webhook payloads.

Have a security concern or question?

Security disclosures and questions can be sent directly to our team. We take every report seriously and respond promptly.

info@dwell-kc.org • Privacy Policy