API Maker

The framework for AI era

Security

API Security Report & Actions

Find where a person could read data that is not theirs, and fix it in one click.

API Maker reads your groups, API users, auth providers, settings and the code of your pre-hooks, and shows where a person could read or change rows that are not theirs. A leak comes with the request that proves it, and many findings with an action that fixes them in one click. The report lives in your Git repository, where your AI assistant can read it too.

See it live

Step through it, slow it down, or open the full canvas.

api-maker/features/api-security-reportLive
  • Scan
  • Critical
  • High
  • Medium
  • Fixed
Score
–/ 100
Open findings
0to fix
Fixed
0by actions or git
Skipped
0with a reason

It reads the whole account. Groups, API users, auth providers, settings and the code of every pre-hook, read and never run. Each open finding takes points off 100: 20 for a critical one, 10 high, 4 medium, 1 low.

How it works

  1. It reads the whole account.

    Groups, API users, auth providers, settings and the code of every pre-hook, read and never run. Each open finding takes points off 100: 20 for a critical one, 10 high, 4 medium, 1 low.

  2. Allowed is not the same as scoped.

    The group lets the shop app read orders and alice signs in with her own token, but no pre-hook limits the rows: she gets the orders of every customer. The finding comes with the request that proves it.

  3. One click installs the fix.

    A row scoping pre-hook: the owner column goes into every filter with $and, the owner is stamped on every write, aggregate is refused. You can edit the code first. The account is scanned again right after.

  4. Only her own rows now.

    The same request returns the two orders of alice. Asking for the orders of customer 23 matches nothing: her filter is joined to the owner with $and. Aggregate, which no filter can scope, gets 403.

  5. Every finding has its action.

    Revoke a sensitive system API, block inline SQL, or skip a finding with a reason, like reference data everyone may read. A skipped finding leaves the score and its reason is kept in git.

  6. It keeps watching while you work.

    With a local client connected, a change in the account is scanned within minutes and the report is committed to git. Your AI assistant reads it there, fixes the finding, and the next scan confirms it.

What you get

Rows of the caller only

For every table your groups reach, it checks that an active pre-hook limits every API to the rows of the person behind the request, merges the filter with $and, stamps the owner on writes and refuses aggregate and distinct.

Groups that reach too far

Broad flags like all collections or all system APIs, sensitive system APIs such as EXECUTE_PLAIN_QUERY and GET_SECRET, bulk update and delete grants, and groups nobody uses.

Tokens and public APIs

Passwords inside tokens or stored in clear, providers without a groups column, tokens that live longer than 30 days, and APIs that need no token at all.

Actions that fix it

Add a row scoping pre-hook, add a column to a token, require a person token, freeze a group to an explicit allow-list, revoke grants or block inline SQL. You see the code before it is saved.

Skip with a reason

Some findings are fine, like reference data everyone may read. Skip them with a reason: they leave the score, and the reason is kept in git for your team.

Fresh for your AI assistant

While a local client is connected, changes are scanned on their own and the report is committed to git: README.md, report.md, report.yaml and actions.yaml.

An example

A shop with customer logins

Customers sign in with their own token and the app calls the generated APIs of orders. The report sees that no pre-hook limits orders to the rows of the caller, shows the request any customer could send to read every order, and installs the pre-hook in one click. The next scan confirms it.

The request that proves a findingterminal
# every row of "orders", with the token of any person allowed on it :curl "$BASE/api/schema/$ADMIN/shop/main/orders?limit=1000" \  -H "x-am-authorization: $APP_TOKEN" \  -H "x-am-user-authorization: $PERSON_TOKEN"

A finding about rows shows how it is exploited. Here any customer gets every order, because no pre-hook of orders reads the person behind the request.

The pre-hook that one click installsRow scope - orders.ts
const OWNER_COLUMN = 'customer_id';const IDENTITY_FIELD = 'id';async function main(g: T.IAMGlobal) {    // Custom APIs, schedulers and events run under their own rules : only real callers are scoped.    if (!g.req.isApiRequestFromUser) return;    const person = g.req.auth?.authAMDB;    const me = person ? person[IDENTITY_FIELD] : undefined;    // ... 401 without a person token    const scope = { [OWNER_COLUMN]: me };    // MERGE, never replace : $and keeps what the caller asked for and adds the owner on top    const merge = (existing: any) => (existing && typeof existing === 'object' && Object.keys(existing).length        ? { $and: [existing, scope] }        : { ...scope });    const apiId = g.req.reqInfo?.apiInfo?.id;    if (QUERY_FIND_APIS.has(apiId)) {        g.req.query.find = merge(g.req.query.find);        stamp(g.req.body); // update-by-id and replace-by-id : the owner of a row can not be handed over        return;    }    if (BODY_FIND_APIS.has(apiId)) {        g.req.body = g.req.body || {};        g.req.body.find = merge(g.req.body.find);        if (g.req.body.updateData) stamp(g.req.body.updateData); // update-many        return;    }    // ... save and master-save : the owner is stamped on every row    // Fail closed : aggregate and distinct can not be scoped generically, so they are refused.    g.res.statusCode = T.EStatusCode.FORBIDDEN;    throw new Error(`API ${apiId} is not available for row scoped users.`);}module.exports = main;

Generated for the owner column and the field of the token you pick, shortened here. Edit it before saving if you want: the report reads the code again on every scan.

The report in your repositorysrc/API Security Report/report.md
# API Security Report> Generated by API Maker. Read only : work on the findings below, then rescan from the admin panel. See README.md.- Generated at : 2026-09-29 10:00 UTC- Score : **52 / 100** (grade D, Data at risk)- Findings : 5 open, 0 skipped, 0 fixed...## Findings### Row gate : does every collection limit persons to their own rows ?#### [CRITICAL] "orders" is not scoped to the rows of the caller

Next to it: README.md for people and AI assistants, report.yaml with the same content, and actions.yaml with the skipped findings and their reasons.

Good to know

  • Nothing in a database says who owns a row: the owner column is a scored guess, from a relation to the users table, a column named after it, or names like user_id and created_by. Pick another column in the fix dialog when needed.
  • Aggregate and distinct can not be scoped by a filter: the generated pre-hook refuses them for row scoped callers. Serve those needs from a custom API.
  • When the token of a database auth provider does not carry the owner column, an action adds it to the token first. People get it at their next sign-in.
  • Automatic scans run while a local client is connected, and commit only when the account has a Git repository.

Questions

Does the scan run my hooks or call my APIs?

No. It reads the settings of the account and parses the code of your pre-hooks as TypeScript, without running it. Nothing changes until you click an action.

How is the score computed?

Every open finding takes points off 100: 20 for a critical one, 10 for high, 4 for medium and 1 for low. Skipped and fixed findings take nothing. 90 and more is grade A, then B from 75, C from 60, D from 40, and F below.

What happens to a skipped finding?

It leaves the score and keeps its reason. The reason is written to actions.yaml in git, so your team, or an AI assistant working on the repository, knows the decision. You can open it again at any time.

How often do the automatic scans run?

While a local client is connected, the next scan comes 100 times the duration of the last one later, between 1 and 30 minutes. When nothing changed in the account, nothing is scanned, saved or committed.

Can an AI assistant work with the report?

Yes. It reads report.md in src/API Security Report/, fixes the hooks, groups or providers in their own folders and commits. The next scan shows the result.