WhatsApp us

Blog6 min read29 Oct 2026

API access control for internal systems: how we run it

Every internal API call needs two credentials, a key for the system and an actor for the person or agent, checked in middleware. How we design and test the gate.

API access control for internal systems: how we run it

By KYN AI Advisory Team — AI implementation specialists, Singapore

We put two credentials on every internal API route: a key that identifies the calling system, and an actor that identifies the person or agent acting. Both are checked in middleware, before any route code runs, and a missing or invalid one returns an error. A key alone tells you which program called. It does not tell you who is responsible. The actor makes every write attributable. This article explains the design, the reasons and the tests.

What problem does the two-credential gate solve?

Internal systems accumulate routes. A dashboard calls an API. A scheduled job calls it. An agent calls it. A script someone wrote last year calls it. Each route was added for a reason, and most were never given an access review.

Three failures follow.

  1. Forgotten routes. A route added for a test stays open. Anyone who finds the URL can call it.
  2. Shared secrets. One key is used by five callers. When something goes wrong, the log says "the key did it".
  3. Per-route checks. Authorisation is coded inside each handler. One handler forgets. The gap is invisible until someone finds it.

The fix is to move the check out of the routes and make it the default. A route is closed unless it passes the gate.

What are the two credentials?

| Credential | Identifies | Example | Lifetime | |---|---|---|---| | System key | The calling application or job | Dashboard front end, nightly job, WhatsApp worker | Long, rotated on a schedule | | Actor | The person or agent behind the call | A named user session, or an agent's own account | Short, tied to a session |

The key says which system is speaking. The actor says on whose behalf. A valid key with no actor is rejected for any write. A valid actor with no key is rejected too, so a stolen session token alone cannot be replayed from a script.

Actors come from the cloud provider's identity service or the company's single sign-on, such as Microsoft Entra. Humans have named accounts, with no shared logins. Agents have their own restricted accounts, separate from every human's, so an agent's actions are never recorded under a person's name.

Where is the check enforced?

In middleware, ahead of routing. Every request under the API path prefix passes through it. The middleware:

  1. Reads the key and the actor from the request.
  2. Rejects the request if either is missing, expired or unknown.
  3. Loads the actor's permissions: which routes and which data this actor may touch.
  4. Attaches the actor to the request context, so downstream code and the logs both use the same identity.
  5. Rejects anything the permissions do not allow.

Because the check is in one place, adding a new route does not require remembering to secure it. A new route is secured by default. To open one deliberately, such as a health check, you add it to a short, reviewed allowlist. That list is small enough to read in a minute.

How does the database enforce the same rule?

Middleware is the first layer. It is not the only one. The second layer is row-level security in the database: the connection carries the actor, and the database filters rows to those the actor may see. If a handler has a bug that forgets a filter, the database still refuses the rows.

Two layers fail differently. A bug in routing does not weaken the database policy, and a mistake in a policy does not open an unauthenticated route. For the database side in more detail, see multi-tenant database security: what to ask your web developer.

Connections use one restricted account per user per session. They do not use a shared superuser. That makes "who read this record" a question the log can answer.

What do we log?

Every request that passes the gate writes an entry with:

  • the actor and the system key identifier (never the key itself);
  • the route and method;
  • the time;
  • the result, allowed or denied, and the reason for a denial;
  • for writes, the record changed and the before and after values.

Denials matter as much as successes. A run of denied calls from one key at 3 a.m. is how you find a leaked credential. Logs are append-only and sit in the client's own cloud account.

What actions need more than the gate?

Authentication says the caller is known. It does not say the action is wise. Some actions need a further step even from a valid actor:

  • sending an outbound message to a customer;
  • moving money or approving a payment;
  • filing with a government body;
  • deleting records.

These wait for a named person. An agent can prepare the action and place it in a queue. A human approves. The approval is logged with that person as actor. See how to set approval gates for high-risk AI agent actions.

How do we test the gate?

We treat the gate as a feature with its own test suite.

  1. Route inventory test. A script lists every route in the build and requests each one with no credentials. Every route except the allowlist must return a refusal. A new route that forgets the gate fails the build.
  2. Credential matrix. For each route, four calls: no key, bad key, key without actor, key with actor lacking permission. All four must be refused.
  3. Cross-actor test. Actor A tries to read actor B's records. The database must return nothing.
  4. Rotation drill. Rotate a key. The old one must stop working at once and the dependent systems must pick up the new one without a code change.
  5. Agent isolation test. An agent account tries a route outside its scope, and tries to approve its own queued action. Both must fail.

The route inventory test is the one that earns its keep. It catches the forgotten route at build time, not in an incident.

What are the trade-offs?

  • Friction. Every new caller needs a key and an actor. That is the intended cost.
  • Key management. Keys need storage in a secrets manager, a rotation schedule and an owner. Skipping that turns the gate into theatre.
  • Latency. The permission lookup adds a small delay per call. Caching permissions for the length of a session keeps it negligible, with revocation cutting the cache.

Where KYN fits

KYN applies this gate to every internal system it builds, inside a cloud account in your name. If you end the engagement, you can revoke KYN's role and everything keeps running. See infrastructure, integrations and security. The first 14 days are a review of your stack and your team's access habits; a full build ships in under 90 days. Pricing is a one-off build fee and a retainer of at least twelve months.

Frequently asked questions

Is an API key enough to secure an internal system?

No. A key identifies a program, not a person. If five tools share it, the log cannot say who acted. Pair it with an actor credential so every write is attributable.

Why check access in middleware instead of in each route?

One check in one place is secure by default. A new route cannot forget it. Per-route checks depend on every developer remembering every time.

Do AI agents get their own accounts?

Yes. An agent uses its own restricted account, with narrower permissions than any person. Its actions are logged under that account, and it cannot approve its own outbound or financial actions.

Checked 30 October 2026.

Curious whether Marketing agents fits your business? Talk to KYN on WhatsApp — no forms, just a conversation.

Start Building →

Written 29 Oct 2026 · Checked 29 Oct 2026