Open-source agentic enterprise governance is a grant, a rule and a record
Agentic enterprise governance is the rule set an agent actually runs under, and three artifacts carry it: the grant, the action policy and the approval record. Kortix is open source, so all three sit in the project's git repository beside the agents they bind.
An approval record, read back through the SDK
const { approvals } = await p.approvals.list();for (const approval of approvals) { if (approval.action === 'gmail.send_email') { await p.approvals.resolve(approval.execution_id, 'approve'); }}await p.approvals.resolve('<execution_id>', 'deny', { note: 'Send it to the ops list only.' });Source: https:/
The two places a rule is written
The agent block grants what the agent may use, and the policy block decides what each call does.
kortix.yaml
agents: worker: permission: allow tools: all connectors: all workspace: { project_repository: true }Source: https:/
policy block
policy: default_mode: riskpolicies: - match: gmail.send_email action: require_approval conditions: - arg: to match: "*@example.com"approvals: ttl: 4hSource: https:/
A framework controls nothing without a file
A risk register, a policy framework and a steering committee can all exist while an agent drops a production table. None of them sits in the path of the call. What sits there is small. An agent reads a grant, a rule decides each call, and a record keeps the decision. Governance that holds up in an incident review is the writing and the staffing of those three. Nothing else in the program has that property.
Kortix keeps all three in the project's git repository, beside the agents they bind. The manifest is a file a reviewer reads. A rule change arrives as a diff, and the decision on a session's work arrives as a change request.
The grant: what the agent may use at all
An agent's grant is the list of registries it may reach: tools, skills, commands, extensions, connectors, secrets, apps, subagents and kortix_permissions. The same block decides whether the session gets a checkout of the repository. The grant lives in the agent's own block in kortix.yaml, so one screen shows what an agent may use before anyone tells it what to do.
The starter grants everything. Its worker declares permission: allow, then tools: all, skills: all, connectors: all, secrets: all, and workspace: { project_repository: true }. A project created this morning begins with one agent that may use every tool, connector and secret the project has.
The default opens every door, and the other direction is enforced as well. A registry entry gives no agent anything on its own: an agent that omits its skills, subagents, commands, extensions, connectors, secrets, apps or kortix_permissions grant gets none of that registry, and kortix validate prints none (default-deny) beside each one it leaves out.
Three keys run the other way, and a reviewer who assumes default-deny across the board will misread them: an omitted tools grant is all (kortix validate warns), permission defaults to allow, and codemode is on.
Governance starts at the first commit that replaces all with names. secrets: [HELPDESK_TOKEN] is a scope. secrets: all is a claim that the project holds no credential the agent should not have. Most projects cannot make that claim honestly for long.
The action policy: what happens on one call
The rule layer is where the enterprise questions get answered. Kortix states the model in one sentence: "You set allow, ask or block per action, and a rule can match on a glob, a regular expression, or the arguments of the call itself." The sentence after it matters as much. Nothing is switched on for you: a project with no policy declared runs every action.
Two keys do the work, and they are easy to confuse. An agent's permission block decides per tool with allow, ask and deny. That is how "git push *": ask holds one shell command and lets the rest run. Connector rules are a separate list with three actions of their own, always_run, require_approval and block, and each rule matches a call written as <connector-slug>.<tool>. Read the docs for the full key list.
match takes a glob, such as *.delete* or gmail.send_email, or a pattern in slashes for a regular expression. The conditions list is the part a console rarely offers. Every condition must hold, each one names a dot path into the call's arguments, and each compares that argument to a glob or a regex. A rule on the recipient of an email is a different control from a rule on the tool that sends it.
Order is documented, so a reviewer can test the claim. Project policies are read first, then the calling agent's policy set on that connector, then the connector's own base rules. With no match, a sensitive connector holds the call for approval; otherwise policy.default_mode decides, and that key starts at allow_all.
The record: who approved which call
An approval that leaves nothing behind is a conversation. Each held call produces a record with five fields: execution_id, action, session_id, requested_at and expires_at. A decision covers that call alone, and the note a person writes travels to the agent as an instruction. An approval nobody decides expires at approvals.ttl, which is 24 hours unless the project sets something between five minutes and 30 days.
Work leaves a second record, and the change request is that record: the diff the session produced, the branch it came from, and the person who merged it. Every session boots an isolated Linux cloud computer with your repo and your tools already on it, on its own git branch. The branch is the run's identity: the session id, the sandbox id and the branch name are one and the same string.
The two records answer different questions, which is why a company needs both. The change request says what changed and who allowed it. The approval record says which call was held, in which session, at what time, and what the person told the agent to do about it. An audit log adds the plumbing around them: a clone or fetch is recorded as git.clone, a push as git.push.
The first five rules to write
Five rules cover most of the risk in a first agent. Each one is a few lines in the file that already holds the manifest. The patterns are shapes to copy into a project; the thresholds belong to the business that sets them.
- Production writes. Block the deletes with
- match: "*.delete*"andaction: block, so a call that removes a record fails instead of queuing. Hold the releases with- match: "*.deploy*"andaction: require_approval. - Customer data reads.
default_mode: risklets every read run, so a read needs a rule of its own. Write- match: "*.get_*"withaction: require_approval, then a condition onarg: tablematching"customer*". Reads of the customer tables then wait for a person, and reads of everything else do not. - Spend. Match the argument that carries the number. Under a
require_approvalrule,conditionswitharg: amountandmatch: "/^[0-9]{4,}$/"sends a call of that size to a person and lets a small one through. - External comms.
- match: "*.send*"withaction: require_approval, and a condition onarg: tothat matches"*@yourcompany.com"withnegate: true. Internal mail runs; anything leaving the company waits. - Credentials. Narrow the grant before writing a rule, so the agent names one secret instead of
secrets: all. Then keep the value out of reach: connector credentials are brokered server-side and never enter the machine; secrets are encrypted per project. A secret the agent must hold as an environment value is a different exposure, and one to write down rather than hope about.
What to reject in a vendor review
Three answers should end a vendor conversation, however good the demonstration was.
Policy you can edit only in a console you do not own. A rule that cannot be diffed cannot be reviewed with the change it governs, and it does not travel if the company changes platforms. Ask for the file.
An approval with no record. A button marked Approve, with nothing that says who pressed it, on which call, with which arguments, is an acknowledgement. A decision that names the call, the session and the time is a control.
Grants that default to everything and cannot be narrowed in the repository. A default of all is survivable when the first commit narrows it in review. It is not survivable when the narrowing happens in a settings page nobody reads.
The two products most enterprise teams already hold are clear about where their control sits. Claude Cowork is now part of Claude. It is available on paid plans (Pro, Max, Ultra, Team and Enterprise); on Enterprise plans an owner has to enable it. Microsoft sells Copilot in three licenses: Copilot Chat (Basic), Microsoft 365 Copilot (Basic) and Microsoft 365 Copilot (Premium), the last covering Copilot, Copilot Cowork and Copilot Code. Answers are grounded in Microsoft Graph and Work IQ, and access is scoped by user permissions.
Both statements describe real controls, held by an account owner and by the directory a company already runs. Neither puts the agent's rule in the repository where the company reviews its own code, which is the question to ask before any pilot.
What it costs to keep running
Most of the cost is staff time, and a program that budgets none of it ends up with policy that blocks the work it was written to protect.
An owner for the queue comes first. An approval held at two in the morning expires, and the agent stops until somebody decides. Name the person, name the backup, and set approvals.ttl to a window the on-call schedule can actually cover.
A review cadence comes second. Rules rot quietly: a connector is added, a tool is renamed, a threshold stops matching the shape of the business. Put the manifest on the same calendar as the access review, and read the diffs rather than the framework.
The repository becomes production, which is the cost teams underestimate. A one-line edit to kortix.yaml can widen a grant, so the change needs the review a deploy gets. The project.gitops.merge grant decides who may land a change request without a second pair of eyes. That decision is worth making once, deliberately, and writing down.
The rule file ships without rules, so the first one is a decision rather than a configuration step. The architecture page covers the machine and the manifest those rules attach to. The build page puts the rules in the order a team commits them.
The questions a security team asks first
- What is agentic AI governance?
Agentic AI governance is the rule set an agent runs under: which tools, connectors and secrets it may use, which calls wait for a person, and what record shows the decision. Rules that no system reads are a statement of intent.
- What is enterprise governance?
Enterprise governance is how a company assigns decision rights and accountability: who may decide, inside which limits, and who reviews the result afterwards. For agents it means a written scope per agent, a rule per risky call, and a record per approval.
- What are the four pillars of an agentic tool?
Nothing authoritative fixes four. The lists in circulation usually separate the model, the tools and data an agent reaches, the memory it keeps, and the rules around it. Keep a pillar only if it maps to a setting somebody can open and check.
- What is an agentic enterprise?
An agentic enterprise is a company whose work runs through agents it can name and constrain: a written scope per agent, a rule per risky action, and a record of who approved what. People still decide what reaches production.
Write the first rule before the first agent
One repository, one manifest, one policy a reviewer can open.