Protect data through explicit permissions
The database should have rules defining who can read, create, change and delete information. Those permissions need to reflect the business structure, including separation between users and organisations. An application with a login can still expose data if access rules are too broad or missing from the paths used to retrieve information.
Imagine a portal where two companies store requests. Someone from company A may know the address of a request belonging to company B, but that does not authorise them to read it. Separation must exist where data is retrieved, alongside being reflected in the interface each person sees.
When a database supports row-level security, rules can restrict the records available in each context. The Supabase RLS documentation explains this mechanism. The practical point I bring to a review is requesting explicit rules and checking their effect with different accounts, rather than relying on the presence of a login screen.
Functions and indirect ways of querying data need review too. One page may use a correct rule while another operation reads with elevated privileges without the necessary filter. The question therefore follows the complete journey: which information reaches the user, through which route and under which authorisation?
Check authorisation on the server for every action
The server should decide whether someone may perform an action using a verified session and permissions stored by the system. Fields sent by the browser must not grant administrative powers. The interface helps guide users, but the decision to allow or refuse an action needs to remain valid outside that interface.
A hidden button can improve the experience by showing only relevant options. Someone can still try calling the operation for editing a request directly. The server must refuse that action when the session lacks permission, regardless of whether the request resembles one that an administrator’s browser would send.
A useful test uses two accounts with different roles. One can read a record; the other can change it. Verify both behaviours and attempt the change using the read-only account. Write down the expected result so future interface changes do not remove protection without anyone noticing the difference.
In Sextas Ímpares #145, about developing with Claude Code, security review accompanies the discussion of building an application. The five rules on this page are also criteria I require in my projects. The Portuguese-language class provides context, but a tool saying it handled security is insufficient: I want evidence of behaviour.
Verify access to the resource identified in a request
Every operation receiving the identifier of a request, file or other resource should confirm that the session can access that specific item. Knowing an address or number does not grant permission. This check needs to cover reading, editing, exporting and deleting, according to the actions that the application makes available to users.
Consider downloading a proposal. An authenticated user may access their own proposal without having access to all the others. If they change the identifier in the address, the system should refuse the unrelated document. The same reasoning applies to private images, audio, internal notes and results from an AI task.
This test becomes particularly important as an application grows. An initial page may be protected while a new export reuses the identifier without repeating the required check. Reviewing routes by resource helps reveal those differences. The database adds protection, while application code still validates the concrete operation being requested.
For business AI agents, apply the control before giving context to the model. If a session can only consult certain requests, the tool should return only those requests. The model should not receive someone else’s information accompanied by an instruction to ignore it when producing its response.
Keep keys and credentials out of public content
Keys granting access to private services should remain on the server and outside published code, pages and shared records. Give each integration only the access it requires. Review files, version history and application responses, because a key can be exposed through several routes even when the main configuration file is correctly protected.
A variable used in the browser can be inspected by website visitors. Requests to services requiring a secret should therefore pass through an authorised server operation. The browser receives only the permitted result, without receiving the credential used to perform work on behalf of the application or its users.
Prepare material before a demonstration or support request as well. A screenshot may show a key, a contact or customer information. In classes, there are decisions about what I can show. That care should continue in documentation and examples sent to AI tools during development or troubleshooting.
If a credential has been exposed, removing visible text may be insufficient: replace the key and review the places where it appeared. For everyday prevention, I prefer project-specific access and limited permissions. A sending integration, for example, should not need administrative powers over the entire platform to perform its task.
Validate inputs and limit work requested from AI
Incoming information should be validated before being used, stored or presented to other people. Define permitted fields, formats, sizes and usage limits. Generated or imported content also requires handling: an AI response remains an input the system must check before it causes consequences, even when the text looks complete and convincing.
For a form, validate fields in the browser to help the person and again on the server to protect the operation. The database should reinforce the rules relevant to storage. For uploads, check file type and size, store files appropriately and control who can retrieve them afterwards.
When displaying HTML, prevent received content from executing unintended code. When AI reads a page or document, treat instructions found inside it as external content. The OWASP project for language-model applications includes risks such as prompt injection and sensitive-information exposure, which are relevant when assessing these paths.
I also set usage and cost limits. A feature generating text or processing files can be abused without exposing data. The system should refuse excessive requests, limit the context sent and make failures visible, rather than continuing to consume resources without control when something goes wrong or usage increases unexpectedly.
Ask for evidence and keep reviewing the project
A useful review provides examples of what was tested, observed results and limitations still unresolved. Repeat relevant checks when access, integrations or data change. Security accompanies application maintenance, with clear owners and criteria, because a small change can create a route that did not previously exist or alter an existing protection.
I ask for negative tests: an account unable to read another person’s request, a refused administrative operation and a rejected upload outside the limits. I also want to verify that legitimate users can continue working. A system that blocks everything is not ready simply because information is no longer exposed.
The Claude Code security documentation covers tool permissions and untrusted content. I distinguish that layer from the security of the product being delivered. The article on application planning and the page on development with AI connect these checks to the construction process and decisions made along the way.
To prepare your team for these decisions, explore AI training for businesses. To discuss implementation and project needs, present the context to SpartAds. These criteria guide the discussion; a concrete assessment depends on the system, its data and the actions it permits people and integrations to perform.
