FIELD NOTE / 03

Access and permissions for internal tools

Why sign-in is only the beginning, how to define roles, and how to test whether one user can reach another user's records.

An internal tool can feel private because it has a login screen and only colleagues know the address. That feeling is not the same as an access model. A login identifies a person. Authorization decides what that person may read, change, approve, export or delete. A useful review needs to examine both.

The starting point is ordinary business language. Who should see which records? Who can change them? Who can grant access to someone else? What happens when a person changes teams or leaves? If those questions are unanswered, adding a permissions library will not resolve the underlying ambiguity. Decide the intended behavior before judging the implementation.

Separate identity from permission

Authentication answers a question such as “which account is making this request?” It might use a password, Google sign-in or an identity provider. Authorization answers “may this account perform this action on this record?” A successful sign-in must not automatically imply access to every record in the system.

For example, a project dashboard might show an account’s name correctly while fetching every customer’s data from an API. Filtering the returned data in the browser does not prevent the information from reaching that browser. The relevant check needs to happen at the point where access is granted, including server-side queries and file delivery.

Some applications separate the browser from a backend, while others access a managed database service directly. In either architecture, there must be an effective enforcement boundary. For a database-backed service, this can include correctly configured row policies. The existence of a policy switch is not evidence that the policy expresses the intended rules.

Write a small permission matrix

Use actions and records rather than broad labels like “full access.” For a spending-request tool, rows might be create request, read own request, read team request, approve request, change approved amount, export records and invite users. Columns might be requester, team manager and administrator.

Mark each cell allowed or denied and add any conditions. A manager may approve only requests from their team. A requester may edit only a draft. An administrator may manage membership without being authorized to approve expenses. These distinctions are easier to discuss in a table than after they have become assumptions scattered through code.

Include system actors. A scheduled import, webhook handler or integration account may have more reach than a human user. Identify the minimum access it needs and how its credentials are rotated or revoked. “It runs in the background” is not a reason to leave its permissions unexplained.

Test records as well as pages

Page access is only one layer. A normal user may be prevented from opening an administration page but still be able to call its API. A file may be hidden in the interface but downloadable through a stored link. A record identifier may be easy to change in a request. Each path deserves attention according to its importance.

Create separate test users with synthetic records. Confirm a permitted action first, then attempt the same action with an account that should be denied. Try reading another user’s record, modifying a record outside the user’s team, requesting an export and downloading a restricted attachment. Inspect the result on the server or in the data, not only the message shown in the interface.

Also test absence of identity: a logged-out request, an expired session and a revoked account. A browser can keep an old page visible after logout, so distinguish cached display from new access. The question is whether further protected data or changes remain possible.

Keep team boundaries explicit

Many small tools begin with one team and later gain another. If the data model did not originally include a team or workspace boundary, adding a dropdown may create the appearance of isolation without enforcing it. Queries, background jobs, exports and integrations all need the correct scope.

Do not assume that an email domain is a sufficient membership rule. Contractors, shared addresses and people with access to multiple organizations can break that assumption. Establish membership through the application’s intended invitation or administration process, and review who can modify it.

When a tool genuinely serves only one company, keep that simplicity. There is no need to invent a complex multi-tenant product. But document the assumption, and revisit it before sharing the same deployment with a client or another organization. A business expansion can change the security boundary without a visible change to the interface.

Consider changes over time

Permissions are not static. A person leaves, a team reorganizes, a document becomes confidential, or a task moves from draft to approved. Decide when those changes should take effect and whether cached sessions or tokens can continue to authorize old access.

Pay attention to privileged actions such as changing membership, replacing integration credentials and exporting all records. Keep an audit trail that identifies the actor, action and relevant object without filling logs with confidential content or passwords. An audit trail is useful only if someone can interpret it and the records are protected from casual alteration.

Emergency access also needs a defined procedure. If the only administrator is unavailable, the business needs a recovery route. That route should be controlled and documented, not an undocumented shared password that everyone eventually knows.

What Platform93 can contribute

Platform93 is Supaapps’ open-source foundation for identity and application administration. Where it fits, it can provide building blocks rather than requiring every tool to implement all account management itself. That does not automatically authorize access to your application’s business records.

The tool still has to verify identity correctly and enforce its own rules at the appropriate boundary. A central identity provider cannot know whether a particular expense is within a manager’s approval limit unless that rule is explicitly represented and checked. Integration should be tested against the application’s actual workflow.

You do not need to migrate to Platform93 to work with Launch a Tool. A review can assess an existing login provider, database policy setup or hosting platform. The right question is whether the chosen design enforces the agreed permissions and remains manageable for your team.

A useful first review scope

For a small tool, begin with the main workflow, two distinct user roles, one privileged action and any relevant file access. Write down the expected results, run the checks with synthetic data and record the evidence. This is more informative than announcing that “authentication is implemented.”

A limited review should also list what was not tested. Additional roles, external sharing, integrations and historical data paths may need a deeper assessment. The result should support a specific next decision: restrict access, fix a demonstrated issue, extend the review or proceed with a bounded trial.

Sources

  • OWASP ASVS — security requirement framework for designing and checking application controls.
  • Platform93 source code — inspect the implementation and release documentation rather than assuming a feature guarantees application-wide security.

Your next step

Bring your tool. We’ll work out together what the next useful step looks like.

Explore the service ↗

LAUNCH A TOOL / SUPAAPPS

What have you been building?

Show us where you are. We’ll help you work out what comes next.

Let’s look at your tool

Free 30-minute fit call