All services
Security

Security and auth products

Sign-in, sessions and authorisation built so the boundary is on the server and the client only decides what to draw.

Pricefrom $800

How this one runs

Category
security
Starts with
A free 30-minute scoping call
Engagement
Fixed price, milestone, retainer or fractional
After launch
Thirty days of fixes included
Reply time
Within one business day

About this service

Delivered as OAuth, WebAuthn, and RLS work, under the constraint every product in this catalogue is built under: it has to run without a paid service in the critical path, without a server that must be kept alive, and without a vendor whose pricing can move under you. That began as a budget decision and became a design one.

Scope is agreed on a call before anything is quoted, and what the work does not include is written down at the same time as what it does. If this is the wrong service for your problem, that is a sentence you get on the call rather than a discovery in week three.

How this one goes

What the work actually looks like

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.

What is included

Five deliverables, every time this service is bought. Anything outside this list is quoted separately rather than assumed.

  • 01Social and passwordless sign-in
  • 02Biometric unlock on native
  • 03Two-factor and recovery flows
  • 04Role and permission model read at query time
  • 05The non-admin probe that proves the gate holds

Technologies and tools

The default set for this service. A project with a good reason to differ gets that reason written down before we start.

  • OAuth
  • WebAuthn
  • RLS

Questions

Common questions

The questions that actually arrive, answered in the first sentence.

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.

Why choose this

Four commitments that hold for this service the same way they hold for the other eight.

Built the way it will be maintained

Typed end to end, structured so a second developer can find things, and commented where the reasoning is not obvious from the code. You are not buying a codebase only I can read.

The failure paths are designed, not discovered

Empty, loading, offline and error states are built with the feature rather than after it, because those are what a real user meets on a first run or a bad connection.

You see it running every week

A working demo against the milestone, not a status update. If something slipped you hear it that week, while there is still time to change what we do about it.

Handed over completely

Repository, store listings and documentation are yours. Nothing needed to run or rebuild the product stays on my machine, and nothing is licensed back to you.

Ready to start?

Tell me what you are building and roughly when you need it. The first call is thirty minutes, costs nothing, and ends with either a scope or an honest reason not to proceed.

Related services

Frequently bought alongside this one, or a better fit if this is not quite it.