Building With AI
What I Learned About Web Security While Building My First App
Published 24 August 2026
A screen that works is not the same as a system that is safe to use. Building Site Control Occupancy forced a series of security questions that did not appear on the first dashboard mock-up.
The interface was the easy part
The first useful screens were a scan confirmation and a list of how many people were recorded in each area. Making those screens clearer was work, but it was not the work that changed the project.
The harder questions were about who was allowed to see what, and what would happen if the wrong person could call the same functions the administrator used. Those questions did not come from a textbook. They came from treating the application as something real people might use.
Authentication is not the same as authorization
Authentication is proving who someone is. Authorization is deciding what that person is allowed to do. I had not needed that distinction when the only user was me on my own computer.
Once there were administrators, it was not enough that someone could log in. Viewer, Admin, and Super Admin are different jobs. Seeing occupancy is not the same as changing areas, and changing areas is not the same as managing other administrators. Multi-factor authentication was added for administrator login because a password alone was not a comfortable control for those accounts.
The database has its own permissions
Storing names, companies, and movement records in PostgreSQL through Supabase meant the data lived on a server, not only in a page. A database is not a private spreadsheet just because the website has a login form.
Row Level Security is the idea that the database itself should refuse some requests, even if someone knows an address to send them to. I had never needed that concept until personal information was involved. The lesson was simple to state and slow to take seriously: if the only protection is hiding a button, the data is not protected.
Secrets and tokens are not decoration
Hosting introduced environment variables and keys that must not appear in public JavaScript. A browser identification token for a Site User is also not a password in the ordinary sense, but it still has to be treated as something that identifies a person. If it leaks, the question is who can use it.
I did not need the internal names of every secret to understand the rule: anything that grants access belongs on the server, in configuration that is not published with the website files.
Recovery can leak information if it is too helpful
Site Users do not use a password account. If the browser token is gone, recovery has to find the right person without turning into a directory of other people’s details. Showing a full mobile number to anyone who types a similar name would be convenient and wrong.
The same tension appears in many systems: help the legitimate person back in, without teaching a stranger whether a profile exists. Getting that balance right is product design as much as coding.
Audit logs are for later, when you need to know what happened
When administrators change settings, it is useful to know that a change happened without storing extra personal details in that log. I had thought of logs as error messages. In a live system they are also a record of privileged actions.
You do not appreciate that until something looks wrong and you want to know whether it was a mistake, a permission problem, or an expected edit.
Working and safe are different tests
A prototype can “work” while still answering yes to uncomfortable questions: can a visitor retrieve user information? Can a lower-privileged administrator see data that should be restricted? Can an important action be performed without the required authentication level?
Those tests are not a public vulnerability write-up, and they are not a substitute for a professional security assessment. They are the reason the project went through more than one round of hardening, and later an internal cloud and security review before operational use. AI made it easier to change the code. It did not decide which behaviour was acceptable. That remains a human responsibility, which is also the point of the article about building the first app without being a programmer.
