Flamecloak

Let AI act.
Stay in control.

Flamecloak is the action authorization layer for AI agents, people and automation: let them act, and control what they are allowed to do

Available on request. A person answers every request.

Autonomous software is now allowed to act on your behalf. What it may do is still decided once, at the door, for a whole session. With Flamecloak it is decided one action at a time.

Every organisation has APIs that return things nobody should touch casually — bulk exports of customer data, document downloads, credit decisions, irreversible writes. Access control says who can reach the system. Nothing says this specific action, right now, needs a person to say yes.

That gap is the canonical insider-risk vector, and it is getting worse, because the number of things holding your credentials is going up.

Flamecloak fits the proxy you already run — Envoy, NGINX, Traefik, your API gateway — or your own code, through a small SDK. It starts in observe mode, blocking nothing, and within thirty minutes tells you which endpoints returned personal data, to whom, and how much. Then you choose the handful that matter, and from then on none of them happens until an accountable person has said yes.

None of this needed anybody to break in.

Four shapes of loss, every one of them carried out by an account that was allowed to do it.

  • Bulk export, valid credentials
  • Documents pulled one by one
  • Payments released unattended
  • Agents acting with your keys

All four are permitted. That is the problem.

Three numbers, one report, and the page for each.

The account that does the damage is usually allowed to.

Most serious data loss involves credentials that were real, a permission that was current, and a request that looked like every other request that day. Nothing was broken into. Somebody who was supposed to be able to do it did it, at a scale nobody had thought about, and the system did exactly what it was configured to do.

That is not a configuration mistake. Permissions are granted to people and to systems, never to individual actions. Somebody who needs to read customer records to do their job can, by the same grant, read all of them at once. A script with a valid key does not get more suspicious the ten-thousandth time it runs. The question was asked once, at the door, and never again afterwards.

So the useful question goes unasked, because there is nowhere to ask it. Not "may this account do this" — every system answers that already, instantly, correctly, and it is not the question. The one that matters is whether this particular thing, at this size, right now, should be done at all.

One approved session, and the one action inside it that nothing decidedA four-hour session drawn as a horizontal bar. Twelve routine calls sit inside it as small marks. A thirteenth mark, taller than the bar and in amber, is an export of four hundred thousand customer records. A bracket above the whole bar reads: what access management decided. A bracket below the single tall mark reads: what nothing decided.what access management decided09:00 sign-in13:00 expirywhat nothing decidedexport · 400,000 rowsDOB, national ID

Organisations where some actions must not happen until a named person says yes.

The agent that was given a goal, not a list

Software that decides its own next step now holds your credentials. It was told what to achieve and not which calls it may make to achieve it, so the boundary it works inside is whatever the key allows. Nobody is watching the session it is in, because there is no session and nobody in it.

POST /v1/refunds, issued by an agent, at four in the morning

Held until a person has seen which agent is asking, and for what.

no obligation names this yet

The export nobody looks at

An analyst pulls customer records to answer a question. The same permission that returns one row returns four hundred thousand, with dates of birth and national identifiers among them. Nothing was broken into and no rule was bent.

GET /v1/customers?limit=400000

Held until somebody accountable has seen the size of it.

GDPR Art. 5(1)(f) · Art. 32

The payment that cannot be recalled

A scheduled job releases a payment run at four in the morning. The person answerable for it has never watched one go out.

POST /payments/runs/{id}/release

Held until the person answerable for it has watched one go out.

financial controls: segregation of duties

The deletion that was meant to be one row

A maintenance script, a missing clause, and a table instead of a record. The difference between an inconvenience and an incident is whether anything stood between the intent and the effect.

DELETE /records

Held until the shape of what is about to go is on somebody's screen.

GDPR Art. 5(1)(f) · retention and integrity

The document that walked out

A support tool lets one contract be opened by its id. Nothing stops the ids being asked for in order. Over a weekend the whole folder leaves: signed agreements, identity packets, the scans somebody sent once and forgot about. Every request was permitted and every one was answered correctly.

GET /documents/{id}, iterated across a range

Held the first time it is asked. There is no tenth to wait for, and so no threshold to stay under.

GDPR Art. 32

The account that was not theirs

A colleague's password is stolen, and late at night somebody signs in with it and starts reading records, one person at a time. By morning it is hundreds of thousands, and every single request looked like work. Nothing here finds the hole they came in through, and somebody patient enough to keep to normal hours and a normal pace is slowed, not stopped.

GET /people/{id}, read in order, through the night

Refused outside the hours it is used and past the pace it usually sees, and somebody is told within the hour.

GDPR Art. 32 · Art. 33

The decision that changed someone's life

An eligibility decision is released without a person on it. A credit line, a claim, a place on a list. It is correct as often as the model is correct, and the person it happened to has nobody to ask, because nobody decided. What is held here is the release, not the judgement: the record says a named person answered, never that the answer was right.

POST /decisions/{id}/release

Held until a named person has answered, and the record says who.

GDPR Art. 22

Where it sits, and what it signs.

It runs in the path the request takes, in front of the systems it protects — run by us, or inside your own network. It starts in observe mode, holding nothing, and reports what is actually being asked for.

Where it sits in your infrastructureThree plates left to right inside a dashed boundary labelled: your network. The first is the caller, which may be a person, a script or an agent. The second is Flamecloak, which sits in the path the request takes and either forwards the call to your systems or holds it. The third is your systems. A branch drops from Flamecloak to an approver and returns a signature. Nothing in the picture leaves the boundary.your networkcallerpersonscriptagentFlamecloakin the request pathforwards it, or holds itapproversignedyour systems

It watches before it holds anything.

The first thing you get is a description of your own traffic: which endpoints return the most, which return personal data, and who is calling them. You decide what deserves a hold from that, rather than from a list we wrote.

Then a person decides, and the record says who.

A held action stops and never reaches your systems until somebody entitled to authorise it has said yes, and the record says who. Whoever answers can see as much of the request as you choose to show them, so a yes is not given blind.

What observe mode reports back in its first period
endpointcallsrows returnedpersonal datacallers
GET /v1/invoices8,417412,006122
GET /documents/{id}22,94022,94034
DELETE /records941,89025
GET /v1/customers?limit=62,400,00041
POST /payments/runs/{id}/release313103
GET /v1/customers/{id}1,2041,20449
An illustration of what the first report is meant to contain, not a screenshot of a running system. None of these figures was measured anywhere.
How a held action is decidedFive moments in order: a consequential action is asked for; it waits instead of running; the right person is asked; they answer; it proceeds, or it does not. A record is kept whichever way it goes.01request arrives02it waits instead of running03the right person is asked04they answer, yes or no05it proceeds, or it does not

Two ways in: in front of your API, or inside your code.

The proxy holds the HTTP calls that already pass through a proxy. The SDK holds everything else: a background job, a queue worker, an agent’s tool call, a payout that never touches a route of yours. Both ask the same people and write to the same record.

In front of your API

For calls that already go through a proxy or an API gateway. A held call stops there and never reaches your systems until a person has said yes. Your API does not change: the caller waits for the answer, and one script tag or the SDK handles that waiting for it.

Inside your own code

For everything a proxy never sees. Your code asks one question before it acts, and does the action only when the answer is yes. There is no route to add and no network change to make.

  • No change to your infrastructure.

    A package and one call, in the place your code already decides to act. No proxy, no route, no nginx block.

  • Named actions, each with its own people.

    refund, payout, export: each has its own rule, its own approvers and the order they are asked in, set in your dashboard and signed with a passkey before it takes effect.

  • Rules on the values your code sends.

    A refund above 500 waits for a person and one below goes ahead at once. The rule reads the amount your code passes, so you decide what is worth a person’s time.

  • Covers what has no HTTP call.

    Scheduled tasks, queues and an agent’s tool calls are held the same way an API call is, and land in the same record.

  • Alongside the proxy.

    One account can use both: the proxy in front of the API and the SDK in the workers behind it.

  • A defined answer when we cannot be reached.

    While we cannot be reached, actions you only watch go ahead, and actions that need a person, or are forbidden, are refused rather than let through.

One call before the action runs

npm install flamecloak-sdk
import { Flamecloak } from 'flamecloak-sdk';

const flamecloak = new Flamecloak(process.env.FLAMECLOAK_KEY);

const decision = await flamecloak.authorize({
  action: 'refund',
  parameters: { amount },
});
if (decision.allowed) {
  // Do it here, with decision.decisionId as its idempotency key.
}

JavaScript and TypeScript, Python and PHP. The packages are public; the key they need comes with Flamecloak, which is available on request. The answer can also arrive by webhook instead of a wait.

npm · PyPI · Packagist · The guide

Four things we will be held to.

None of it is checkable yet, because there is nothing to run it against. When there is, this page will say so and change.

Run by us, or inside your own network.

Most teams let us run it for them. Teams that cannot send traffic through anyone else run it in their own infrastructure, in front of the systems it protects, with no live connection to us and no account of ours whose outage can stop their business. Either way we keep no copy of your traffic beyond what you choose to show your approvers, for as long as you choose, and the record is yours.

Every decision leaves a record you can check without us.

Who asked, what exactly was about to happen, who was entitled to answer, who did, and when. The record is tamper-evident, and an auditor can verify the whole sequence independently — with a tool that never contacts us and does not need our permission.

One entry in the record
who asked
svc-reporting (script), acting for a.dumitru
what was about to happen
a bulk export of customer records · 400,000 rows
who was entitled
data protection officer, head of support, CTO
who answered
M. Ceban · confirmed on their own device
when
2026-03-11 09:41:57 UTC
previous entry
any later change to it is detectable
Verifiable with a tool that never contacts us. The values above are an illustration of the format.

It never decides. A named person does.

There is no model here and no scoring. The gateway works out which humans are actually entitled to authorise this particular action, and puts the question to one of them. The judgment is theirs, the responsibility is theirs, and the record says which of them it was.

The unit is the action, not the session.

Access control decides who may be in the room. This decides what may happen while they are — this export, at this size, right now. It asks the question your existing controls ask once, at the door, and never again afterwards.

When one yes is not enough.

Some actions deserve more than one person’s attention, and some calls give themselves away by when they arrive or how many come, rather than by what they ask.

Several people, not one.

An action can need more than one yes: everyone you list, or as many of them as you choose. A stolen phone or a borrowed account cannot approve it alone, because the others still have to agree, and nobody approves their own request.

Outside its usual hours, it waits.

Say when an action is usually called. A call at two in the morning, to an API that is only ever called by day, goes to a person or is refused, as you chose, instead of going through because nobody was awake to see it.

A sudden flood is stopped.

Say how many calls an action usually sees. When an endpoint that gets a few calls an hour suddenly gets thousands, the excess waits for a person or is refused instead of going through. The people who approve are told once, not for every call.

Why run it with us.

Most teams let us run it, and the reason is not convenience. A guard is only as strong as the place it stands.

The guard is not on the server it guards.

If someone takes over one of your servers, they hold its code and its keys, but not the gate in front of your API. They cannot switch it off, loosen its rules or approve their own calls, because none of that happens on the machine they took.

The people who approve are not on that server either.

An approval comes from the approver’s own device, signed with their passkey. A compromised server can ask as often as it likes; it cannot answer for them.

The record is kept where an attacker cannot edit it.

Every decision is written on our side, in a record nothing can change afterwards. Someone covering their tracks on your servers cannot rewrite who approved what, or make a refusal disappear.

Inside your own network, if you need it.

Teams that cannot send traffic through anyone else run it in their own infrastructure, in front of the systems it protects, with no live connection to us. Kept on machines apart from the servers it guards, it keeps the same distance from them.

What it will not do.

  • It does not decide anything. It puts the question in front of a person; the judgment is theirs and so is the responsibility for it. Anyone selling you automated judgment about identified people is selling you a different and much larger problem.

  • It does not know whether the person was right. It can record that they were asked, what they were shown, and what they answered. Whether that was the correct answer is not a thing software knows.

  • It cannot see what does not pass through it. Data pulled straight out of a database by somebody with direct access leaves nothing for this to hold, and no amount of configuration changes that. A deployment that gives false assurance is worse than no deployment.

  • It is not sold off the shelf. It is available on request: you ask from a Tunnel account, a person answers, and what you get is agreed with you. There is no price list.

Leave an address for news.

No newsletter, no drip sequence and no sales call. A message when something changes that you would want to know, and you can leave the list from any email we send.

One address, used for this and nothing else. Leave the list from any email we send.

Or ask for access.

Create a Tunnel account and ask for Flamecloak from your dashboard. A person will get in touch to set it up with you. Asking commits you to nothing.

Create an account

Questions people ask about this

Can I use this today?

Yes, on request. Create a Tunnel account and ask for it from your dashboard, and a person will get in touch to set it up with you. What you get is agreed with you, and there is no price list. If you are not ready, leave an address and we will write when there is news. Neither one holds you a place in a queue, because there is no queue.

How will it deploy?

In one of two ways, and you can use both. In front of your API: run by us, or inside your own network alongside the proxy or gateway already in front of your systems, where the actions you choose to hold are routed through it and nothing else is. Or inside your own code: an SDK in JavaScript, Python or PHP asks before an action runs, with no route to add and no network change. There is no appliance to buy either way. What it costs you is a route or one call, and a decision about which actions are worth holding.

What will it show me before I hold anything?

It watches first and holds nothing. In observe mode it reports which of your endpoints returned personal data, to whom, how much and how often, and no request behaves any differently while it does. The first useful output is a list of the endpoints you did not know were returning what they return. Nothing is held until you name something to hold.

Does everything have to go through it?

No, and it is built on the assumption that it must not. Only the actions somebody has deliberately chosen to hold are affected; everything else is untouched. A control that has to sit in front of everything is a control nobody deploys.

Can we use it without touching our proxy?

Yes. The SDK holds an action from inside your own code: install the package, name the action in your dashboard, and call authorize() before the action runs. There is no proxy to change, no route to add and no network change. The proxy is the other way in, for HTTP calls that already pass through one.

Which languages does the SDK support?

JavaScript and TypeScript (Node 20 or later), Python and PHP: flamecloak-sdk on npm and PyPI, and flamecloak/flamecloak on Packagist. Other languages are added when a customer asks for one. The packages are public; the key they need comes with Flamecloak, which is available on request.

What happens to our code if Flamecloak cannot be reached?

It gets a defined answer. While we cannot be reached, an action you only watch goes ahead, and an action that needs a person, or that is forbidden, is refused rather than let through. It never fails open on the actions you chose to protect.

Can the proxy and the SDK be used together?

Yes, in one account: the proxy in front of your API and the SDK in the jobs and agents behind it. A held action is decided the same way whichever way it came in, by the same people, and lands in the same record. The dashboard shows which of the two you use.

What happens when the person who should approve is unavailable?

Approval rests with a set of people rather than with one individual, so unavailable has to be true of all of them before it is true at all. If it is, the held action does not proceed. That is the honest failure mode and it is a delay rather than a loss, because the request can be made again. It is also why the choice of what to hold is yours, action by action. You can also put the people in order, so a decision never waits on one person.

What does the person approving see?

As much as your organisation chooses to show. Your application can say who asked and what changes, and the person approving reads that first, marked as your application's statement, because Flamecloak does not check it. Behind the proxy they can also see the request itself, one item at a time as you allow it: the address it came from and roughly where that is, the device, and what it carried. Nothing is shown until somebody allows it and signs that with a passkey, and passwords and login tokens are never shown. What your application says is kept in the signed record; the rest is kept only as long as you choose. Notifications never carry any of it: an email, a Telegram or Slack message and a phone's lock screen say only that a decision is waiting.

Will it slow things down?

For the actions nobody chose to hold, nothing changes. For a held action the latency is however long the person takes to answer, and that is the product rather than a cost of it. We will publish the overhead on the unheld path when there is something to measure it against, and not before.

Is this the same as privileged access management?

No, and it does not replace one. Access management decides who may be inside a system and for how long. This is about the individual actions taken while they are — a different unit of authorization. If you do not have access management yet, that is the more urgent thing.

What happens if your service is down?

Nobody should accept a company of our size as a single point of failure in their production path, and we do not expect anyone to. If we run it for you and our service cannot be reached, actions you only watch go ahead and held actions are refused rather than let through: an authorisation you cannot get is not one you have. If no dependency on us is acceptable, run it inside your own network, where nothing of ours is in your traffic path at all. Being removable is a requirement of the product, not a reassurance in a sales conversation.

How does an AI agent get approved?

A person is asked, the same as for any other caller. What that person sees is which agent is asking, the exact action, and the scope it wants. What they do not get is a score. The product will not tell you whether the agent’s intent looks benign, because that is a judgment about something nobody can inspect, and selling it would be selling the automated judgment this page argues against.

Why will you not say how it works?

Because what is withheld is the internal design rather than the deployment shape. Where it runs, what it shows you before it holds anything, what happens when nobody answers, and what it costs the requests you did not hold are all on this page, because those are the things you would hold us to and they stay true whichever way the implementation goes. How the holding is built is a different question, and answering it hands a competitor the design in exchange for nothing you need before there is something to try.

What of ours ends up in a record you cannot delete?

The record of a held action keeps the shape of the call and whatever your own systems chose to declare about it — an amount, a currency, an order reference. It is append-only on purpose: it is meant to be evidence, so nothing, including us, can edit or remove an entry afterwards. That makes what your systems declare a decision worth taking deliberately, and the product is built to help you take it: it shows how much personal data your own deployment has accumulated, it will not quietly shorten what it is given, and an action can be set to refuse personal data outright. Where you can, declare a reference instead of the thing itself.

Can something be forbidden outright, rather than sent to someone?

Yes, and it is a different thing from a strict approval. A held action normally waits for a person to decide it. You can also mark an action as one nobody may decide: it is refused, nobody is asked, nothing lands in anybody’s queue, and there is no button anywhere that releases it. That matters at four in the morning, when the difference between "someone must approve this" and "nobody may approve this" is the difference between a control and a tired person. The record still says which rule refused and why, so you can count what is being attempted. One honest cost: a rule of this kind refuses rather than asks when it cannot be sure, so it is worth writing narrowly, and the product points out where that could happen.

Where is the decision actually made — on our machines or yours?

Either, and you choose. We run it for you by default; teams that need it run it entirely inside their own network instead, deciding on their own hardware with no live connection to us. In both, the evidence stays with you: the record of what happened and the approvals in it are yours and outlive us. The honest cost of letting us run it: when our service cannot be reached, held actions are refused rather than let through. An authorisation you cannot get is not an authorisation you have, and we would rather stop a payment than wave one through because something of ours was down. Your dashboard says which of the two you are running at any moment.

Where is the company?

"STILL BETA TECH" SRL, registered in Chișinău, Republic of Moldova. Moldova is not an EU member state; we process personal data under the GDPR and under Moldovan Law 133/2011, and we say so rather than implying an establishment we do not have.