DEV Community

Keith Azodeh
Keith Azodeh

Posted on Fully Autonomous

One Login Is Not an Access Policy

A member and a staff coordinator can belong to the same organization, use the same login system, and need very different access. That difference becomes easy to lose when a product brings several disconnected tools into one place.

Disclosure: This article was researched and drafted by an AI agent using my public project documentation and the linked technical sources.

In my work on The Garden platform, one identity connects member and staff experiences. Permissions follow roles, departments, ownership, and explicit access rules. Sensitive fields are protected on the server, and household schedule sharing depends on consent. The Planning Center replacement remains a staged migration; the public case study does not claim that every workflow has finished rollout.

That combination is the design problem: make the system feel connected while preserving the reasons people should see different parts of it.

Give the task a permission of its own

GitHub's October 13, 2026 app-permissions update provides a timely example. Apps and fine-grained personal access tokens can use repository_creation:write to create repositories without the broader repository_administration:write permission previously needed for that task. The broader permission also covers administrative operations such as deletion and transfer. Organization installation still requires the relevant approval.

The narrower permission separates a legitimate task from powers it does not require. That is a useful product decision as well as a security improvement: an administrator can assess the capability being requested more precisely.

Applied to an organizational application, I would start by naming the action. Updating your availability, assigning someone to a team, and editing a person's private record should be separate decisions. A broad label such as "staff" may be one input to those decisions, but it leaves too much unspecified by itself.

These are illustrative design examples, not a description of additional Garden permission names or a claim about its exact schema.

The data model determines what can stay private

My Firebase security field notes start with data modeling because a rule is easier to understand when the stored data matches the access pattern.

Firestore makes this especially concrete. Its field-access documentation explains that Security Rules authorize document reads as a whole. They cannot allow a client to read one field while hiding another field in the same document. Data requiring different read permissions can be stored in separate documents with their own rules.

That matters when designing a convenient profile object. Combining a directory name with restricted internal information may make the first screen easier to build, but the resulting document becomes the unit of disclosure for direct client reads. Removing a field from the React component cannot undo data already delivered to the browser.

Write access is a separate question. The same Firebase guide describes comparing a document's old and proposed state and allowing changes only to selected fields. Read visibility and permission to change a value deserve independent decisions.

For a new system, I would sketch those decisions before settling the profile schema: which information can be read together, which updates belong to the person, and which values require another authority?

Check the route the request actually takes

There is another distinction to keep visible. Firebase's Security Rules conditions guide states that server client libraries bypass Firestore Security Rules. Their credentials and IAM configuration therefore need separate attention. A backend acting on a user's behalf also needs to enforce the application's authorization decisions.

The same guide explains why rules do not behave like result filters. A client cannot query every document and expect Firestore to quietly return only authorized records; the query must satisfy the relevant constraints.

Those details affect implementation reviews. I would trace a direct client request and a server-mediated request separately, then verify the policy applied on each route. Reviewing the visible button alone does not establish what either route permits.

Test the person who should be refused

The Garden's public documentation describes isolated demonstration data, including a synthetic directory used for validation. It distinguishes implementation checks from completed migration and staff acceptance. That is a useful distinction to keep when discussing access testing, too.

For a comparable application, I would write a short set of refusal scenarios alongside the allowed workflows:

  • A member requests another person's restricted record directly.
  • A coordinator attempts an action outside the team they manage.
  • A former coordinator retries the same action after access is removed.
  • A user includes a protected field in an otherwise ordinary update.

These are proposed test cases, not reported Garden test results. Each needs an expected decision and a check at the point that enforces it. A successful page load with demonstration data cannot establish all of those properties.

The tradeoff is real: more precise permissions require more policy, more tests, and a way to explain refusals to users. Excessive exceptions can make the system harder to maintain. Start with the distinctions the actual work requires, and add specificity when a concrete workflow needs it.

For teams consolidating software, GitHub's change is a useful reminder that permission design can improve alongside features. A shared identity removes repeated sign-ins. A precise access policy lets that convenience extend across more workflows without handing every person, integration, or future agent the same authority.

Top comments (0)