Security
At a glance
| Layer | What we do |
|---|---|
| Hosting | AWS, isolated per agency: primary database in Frankfurt (eu-central-1), inbound email in Sydney (ap-southeast-2). A dedicated deployment in AWS Bahrain or UAE is available on request for Gulf contracts. |
| Encryption in transit | HTTPS everywhere, valid certificates, HSTS enabled. |
| Encryption at rest | AWS-managed keys for database + file storage. |
| Authentication | Email + password (BCrypt-hashed), or single sign-on with Google or Microsoft Entra ID (OpenID Connect). |
| Sessions | HTTP-only secure cookies, 14-day TTL, signed. |
| Authorisation | Role-based (Admin / PM / Read-only) per agency. |
| Multi-tenant isolation | Database-level row-level security — agencies cannot see each other's rows even if they tried. |
| Backups | Daily automated, 14-day point-in-time recovery, manual snapshots before risky ops. |
| Audit log | Every action that touches a tenant / owner / property is logged with who + what + when. |
| Magic links | Single-use, 14-day expiry, hashed at rest. |
Login + session security
When you log in:
- Your password is hashed with BCrypt before being stored. We literally cannot see your password.
- A signed session token (JWT) is issued and stored in an HTTP-only, Secure, SameSite=Lax cookie. The token can't be read by JavaScript and can't be sent on cross-origin requests.
- Sessions last 14 days. After that, you log in again.
Single sign-on (Google, or Microsoft Entra ID for organisations on Microsoft 365) works the same way under the hood — we trust the identity provider's assertion and issue our own session token.
What attackers can't do
A few specific concerns we've designed for:
- Reading another agency's data. Database-level row-level security means even if you somehow got our database credentials, you'd still have to identify as a specific agency to read any rows. Bypassing that requires Postgres superuser access, which neither the application nor support staff have.
- Reading a tenant's data without authorisation. Tenants identify via single-use submission tokens. Tokens are scoped to one property and expire after 14 days.
- Hijacking a contractor's magic link. Magic-link tokens are 32 random bytes (256-bit entropy). They're hashed before storage so even our own database doesn't know the plaintext token. Brute force is computationally infeasible.
- Replay attacks on session cookies. Session JWT signatures use a rotating signing key (per-deployment). Old cookies stop working after a deploy.
What we monitor
- Failed login attempts — too many in a row triggers a backoff.
- Unusual access patterns — e.g. an admin downloading every tenant's data in one session — flagged for review.
- Magic-link reuse — magic links can only be opened from the same general region they were originated. Sudden cross-continent use triggers an alert.
What we don't do
- Two-factor authentication (2FA) — not yet implemented. On the roadmap. Workaround: sign in with Google or Microsoft SSO with 2FA/MFA enabled on that account — your provider's MFA then protects PMFriend too.
- IP allowlisting — not yet implemented. On the roadmap for enterprise customers.
- SAML 2.0 single sign-on — not yet implemented. Google and Microsoft Entra ID sign-in (OpenID Connect) work today; SAML, or an Entra directory per customer, is available on request for larger teams.
These are real gaps. We're not pretending they're features. They're on the roadmap and will land as we hire dedicated security engineering.
How we treat security incidents
If we discover a vulnerability:
- We patch it. Most patches deploy within hours.
- We work out which agencies were affected, if any.
- We tell you. Even if you weren't affected. Even if it's embarrassing.
- We publish a postmortem on the docs site with timeline + what we changed.
We don't bury security issues. We've never had a serious one. Aiming to keep it that way.
How to report a security issue
If you think you've found a vulnerability, email
support@pmfriend.com with subject "SECURITY:". We'll respond within
24 hours.
We don't have a formal bug bounty program yet — we're a small team. We will, however, add a sincere "thanks" line to our public security page if you find something material.