Security and auth products โ services โ Ahsan Mahmood
Authentication, authorisation and row-level access control that holds up to a real probe.
Sign-in, sessions and authorisation built so the boundary is on the server and the client only decides what to draw.
You have been told your product is secure.
There is no artefact you can look at to check that. A permission model lives in half a dozen places at once, and none of them prints a report anybody can hand over.
So here is the failure it usually hides.
Most access control is correct in the interface and missing from the database. The button is hidden. The route redirects.
The menu does not render for anybody without the role, and every one of those is a drawing decision rather than a boundary.
The boundary is the query. The query is still there when somebody opens the network tab.
It is rarely found by testing, because the person testing is signed in as an administrator and an administrator passes every check that was supposed to fail.
So the boundary is on the server and the client only decides what to draw.
That is the whole design. Everything else follows from it.
Without a server that must be kept alive, the boundary lives in the database's own rules โ row-level security in Postgres, security rules in Firestore โ rather than in a middleware layer somebody has to pay to keep running.
That has a consequence worth knowing before you buy it. Row-level security filters rather than refuses, so a read somebody should not be allowed to make returns an empty list with a 200, and a forbidden update reports success with zero rows changed.
A test that checks only the status code passes. The probe has to check what came back.
The second consequence is the useful one. A boundary written into the database applies to every path that reaches the data, including one somebody adds next year without reading this page.
What an engagement of this shape covers does not move from project to project.
Social and passwordless sign-in. Biometric unlock on native. Two-factor and recovery flows.
A role and permission model read at query time rather than at render time. And the non-admin probe that proves the gate holds.
That probe is what makes the rest of it checkable. It runs as an ordinary user, with a second user's data already in the database, because a gate tested by the account that bypasses it has not been tested. That is one seeded account, and it is the only step here that produces evidence.
Two-factor is where most of the detail hides. The second factor is easy; the recovery code, the rate limit on the verify step and the audit row saying who turned it off are where the work actually goes.
Passwordless deserves its own sentence. A sign-in link or a passkey takes the password out of the threat model entirely, and what replaces it is a recovery path that has to be written at least as carefully.
2FA Studio, Capacitor Biometric Authentication, WebAuthn Server BuildKit and Capacitor Auth Manager all sit in this area, and each has its own page on this site. OAuth, WebAuthn and row-level security are the default set.
The costs are specific and none of them is optional. Recovery is more work than sign-in.
Signing in is one screen; losing a device, losing a phone number and losing an authenticator are three flows, each with its own way of being abused, and each has to exist before the feature is honestly finished.
A permission model read at query time means every list query carries the filter its rule depends on, so adding a screen means adding a filter rather than adding a check.
The probe costs a second account and real data in the database. That is slower than reading the rules, and it is the only thing that proves them.
There is one more cost you may not expect. Some of the requests that arrive after launch are requests to weaken the model, and those get talked through before anything is changed.
A green build is not evidence that a feature works. It is especially not evidence here, because this failure looks exactly like success from the outside.
The exclusions are the catalogue's rather than this page's. Visual design as a standalone deliverable. Native iOS, so biometric unlock means Android and the platform APIs the web offers, and nothing on an iPhone. Blockchain work. Copywriting and content.
There is also a claim I will not make. No design makes a system secure, and a page that says otherwise is making a promise nobody can keep.
My name is Ahsan Mahmood, and what I can do is put the boundary somewhere a probe can reach it and then run that probe in front of you.
Thirty days of bug fixes at no charge, and after that nothing is automatic.
The parts that stay your responsibility get named on the call rather than found in an incident.
from $800
How long it takes
Small features 1โ2 weeks, an MVP 4โ8 weeks, a full production app 8โ16 weeks. Those are ranges I have hit on work of that shape before. The scoping call settles how many roles the permission model carries and how many recovery paths the product owes, because those two lists decide the work far more than the sign-in screen does.
Every engagement of this shape covers
- Social and passwordless sign-in
- Biometric unlock on native
- Two-factor and recovery flows
- Role and permission model read at query time
- The non-admin probe that proves the gate holds
Built with
How do you prove the access control actually works?
By probing it signed in as an ordinary user, with a second user's data already sitting in the database. That probe is part of the fixed scope rather than an optional extra. An administrator passes every check that was meant to fail, so a gate verified by an admin account has not been verified at all.
Is biometric unlock available on iPhone?
No. Biometric unlock is offered on Android and through the platform APIs the web provides, because there is no Apple Developer account here and nothing I build has shipped to the App Store. That limit applies to every service on this site, not only this one.
Why does a forbidden request sometimes return a 200?
Because row-level security filters rather than refuses: a read you are not allowed to make comes back as an empty list, and a forbidden update reports success with zero rows changed. A test that checks only the status code passes. The probe checks what came back, which is the whole difference between the two.
Do you include two-factor and account recovery?
Yes, both, and recovery is the larger half of the two. Losing a device, losing a phone number and losing an authenticator are separate flows with separate abuse paths. Each one is written and probed before the feature is called finished.
How much does auth and access-control work cost?
$800 USD is the floor for a small, well-defined feature. Everything above that comes from a scoping call, in writing, before any work starts. What moves the number here is how many roles the permission model carries and how many recovery paths the product owes, because each recovery path is a flow with its own abuse case attached.
https://aoneahsan.com/services/security-and-auth-products