Skip to content
Version 1.0.0

Gateway administration

Agentic execution, roles and permissions, startup refusals: what an operator configures and what an auditor checks.

Internal, subject to change without notice. What this page describes belongs to the operation of a deployment, not to the contract the gateway offers to a third-party program. The vendor makes no commitment about it: these names can change from one version to the next, with no deprecation step. A change then shows up at startup or on update, through a message that names what is missing.

The part the vendor does commit to is the relay.

These two routes are the protocol by which a development workstation has its agent commands run on the gateway rather than on the developer’s machine. The workstation and the gateway travel under the same version number: publishing them as a contract would freeze an internal seam.

The workstation asks the gateway to run a command from its agent session. The response is a stream of JSON lines, one per event. A protocol between the workstation and the gateway, versioned with them.

POST /_agent-execution/commands/:identifiant/interrupt

Section titled “POST /_agent-execution/commands/:identifiant/interrupt”

The workstation interrupts a command it started, and that command’s descendants. An unknown command and a command that belongs to someone else get the same response.

The workstation asks what its organization allows: which model providers, which tools. The response carries the policy, its revision, the moment it was produced and how long it remains valid; the workstation applies it and refuses to operate without it. An organization that imposes nothing gets a normal response with no policy in it; an organization the database does not know is a configuration fault and gets an error, never an empty policy. Read-only, without authentication: the workstation has nothing to present. A protocol between the workstation and the gateway, versioned with them.

The workstation submits in batches what its agent did: for each tool called, the target (a path, a command, a host, never the parameters, so never the content of a file nor the conversation), who authorized it, how it ended. A batch carrying an unknown field is refused in full; a batch resubmitted after a network failure is stored only once. Behind the same door as the organization policy: the workstation presents its license. First slice of the act register (#763): nothing is signed, the subject is declared by the workstation.

The workstation asks whether one of its agent sessions can still act. The response says “in force” or “revoked”, and in the latter case since when; it gives neither the author of the revocation nor its reason, which stay with the audit. Revoking a session also revokes its sub-agents. A session nobody has revoked, or that the gateway does not know, is in force. Behind the same door as the organization policy: the workstation presents its license. A read failure answers with an error, never with “in force”.

The workstation asks for the address of the enterprise directory and the public identifier under which the product is registered there, before having any identity at all, which is the whole reason this route exists. The response is read from the directory configuration the gateway already uses to verify tokens, never from a second declaration. A deployment with no directory configured answers “nothing here” without describing its state. The client secret itself is never published.

FieldType
sessionstring
interpreteurstring
argumentsstring[]
variablesSupplementairesRecord<string, string>
sansFluxDeSortieboolean

The subject the command is charged to comes from the verified identity, never from the body.

A body that cannot be read back is refused with a 400, never completed with empty values. Here, word for word, is what the gateway answers in that case. These are the only requirements on form, and the fields none of these sentences names take a default value:

  • The request body must be a JSON object.
  • session must be a non-empty string.
  • interpreteur must be a non-empty string.
  • arguments must be an array of strings.
  • variablesSupplementaires must be an object.
  • variablesSupplementaires.<…> must be a string.

The response is a stream of JSON lines: one line per event, terminated by a newline. The process output travels in it base64-encoded, because decoding it depends on the workstation’s platform.

  • demarre
  • sortie
  • fin
  • erreur

There are four roles, and there is no other: no “super” role. The matrix below lives in the product code and changes only through a product version. What lives in the database is the assignment of roles to subjects, which is operational data.

RolePoleProject scopePermissions
utilisateur-standarduseforbidden3
administrateur-de-projetadministrationrequired5
administrateur-d-instanceadministrationforbidden12
auditeurauditforbidden6

A single subject cannot hold a role from the “administration” pole and one from the “audit” pole at the same time. It is this rule that makes the statement “the auditor does not administer, the administrator does not audit” true, and it is what gives the decision log its value.

A subject with no role assigned gets an empty set of permissions, so a refusal. That is everyone’s state on a fresh instance.

No permission belongs to two roles. An authorization policy installed by the operator can narrow this matrix, never widen it.

PermissionRole that holds itWhat it allows
inference:appelerutilisateur-standardCall an inference endpoint.
usage:lire-le-sienutilisateur-standardView one’s own consumption, and nobody else’s.
execution:lancerutilisateur-standardHave the gateway run a command from one’s agent session.
membres:lireadministrateur-de-projetList the project’s members and their state.
membres:affecter-un-planadministrateur-de-projetAssign or remove a plan for a member.
membres:activeradministrateur-de-projetEnable or disable a member.
usage:lire-le-projetadministrateur-de-projetView the project’s aggregated consumption.
console:administrer-un-projetadministrateur-de-projetOpen the console’s project administration surface.
plans:administreradministrateur-d-instanceCreate, modify, delete a plan and its cap.
fournisseurs:administreradministrateur-d-instanceDeclare a provider: base URL, key header.
modeles:administreradministrateur-d-instanceDeclare a model and its prices.
endpoints:administreradministrateur-d-instanceCreate, route, enable, delete an endpoint.
usage:lire-l-instanceadministrateur-d-instanceView the consumption of the whole instance.
attributions:administreradministrateur-d-instanceAssign and remove roles for subjects.
membres:lire-l-instanceadministrateur-d-instanceList the subjects of the whole instance.
sessions:revoqueradministrateur-d-instanceInvalidate a subject’s sessions immediately.
politique:administreradministrateur-d-instanceInstall an authorization policy.
organisations:administreradministrateur-d-instanceCreate the organization whose policy this deployment serves.
politique-d-organisation:administreradministrateur-d-instanceImpose a policy on an organization’s workstations, that is, fleet governance.
console:administrer-l-instanceadministrateur-d-instanceOpen the console’s instance administration surface.
journal:lireauditeurRead the authorization decision log.
journal:exporterauditeurExport the log to examine it outside the product.
journal:verifier-l-integriteauditeurVerify the log’s chaining and signatures.
politique:lireauditeurRead the policy in force, without being able to install it.
politique-d-organisation:lireauditeurRead the policy imposed on workstations, and everything that was attempted (installations and refusals, with the author of each and what that name is worth), without being able to impose anything.
console:auditerauditeurOpen the console’s audit surface.
RouteCodeWhenBody
exécution agentique401No usable proof of identity accompanies the command.{ "error": "Missing credentials. Set apiKey in your Lemniscate config." }
exécution agentique401A proof is presented and refused.{ "error": "Unauthorized." }
exécution agentique403The subject is on the instance’s revocation list.{ "error": "Your access to this instance has been revoked. Contact the operator of this deployment." }
exécution agentique403No role held by the subject grants the right to have an agent command run. The expected permission is held by the standard user role.{ "error": "Your identity is recognised, but no role you hold carries the right to run agent commands here." }
exécution agentique503The gateway could not read the revocation list, the roles or the policy in force.{ "error": "Authorization decision could not be made, so the command was refused." }
exécution agentique503Agreement was obtained and the log could not record it. The command is then not started at all.{ "error": "Authorization decision could not be recorded, so the command was not run." }
exécution agentique501This gateway runs no agent command, which is its default state. Issued after authorization, so that a caller with no rights at all does not learn what the gateway offers.{ "error": "This gateway runs no agent commands: no launcher is configured (<nom de la variable>). …" }
exécution agentique400The command body cannot be read back: it is not a JSON object, or one of its fields does not have the expected shape. A malformed body is refused, never completed with empty values.{ "error": "<la phrase qui nomme le champ fautif>" }
exécution agentique404The identifier designates no command in progress, or it designates one that belongs to someone else. Both cases get the same response: distinguishing them would make it possible to enumerate other people’s sessions.{ "error": "No such running command." }
src/controlPlane/organizationPolicyRoute.ts500The gateway is configured to serve the policy of an organization its database does not know. This is a configuration fault, and it is reported as such: serving “no policy” would lead a whole fleet of workstations to conclude it is under no restriction, because of a typo.{ "error": "This gateway is configured to serve the organization \"…\", which does not exist in its database." }
src/controlPlane/agentActsRoute.ts400The body of the act submission is not readable JSON.{ "error": "the body is JSON" }
src/controlPlane/agentActsRoute.ts400The batch of acts submitted by the workstation does not pass the allow list: a field the projection does not know (the raw parameters of a call, in particular), a missing required field, a value outside a closed list, a reason longer than 300 characters, or a batch of more than 500 acts. The whole batch is refused and nothing is stored, so that the workstation resubmits it once corrected rather than losing part of it without knowing. The body names the offending act and the reason.{ "error": "acts refused — act #<n>: <raison>" }
src/controlPlane/identityDiscoveryRoute.ts404No enterprise directory is configured on this deployment, or the one that is configured is not acceptable. The response does not say which of the two, nor what is missing: describing the deployment’s state would tell an attacker what is left to get around.{ "error": "not_found" }
src/controlPlane/requesterLicense.ts401The request presents no valid Lemniscate license: no header at all, an expired license, or a license signed by someone else. All three get the same refusal, without saying which applies: distinguishing them would tell the requester what is left to get around. The remedy is the same in all three cases: ask the administrator for a license.{ "error": "This gateway serves an organization's policy only to a workstation that presents a valid Lemniscate license. Present it as Authorization: Bearer . If you have none, ask the administrator who deployed this gateway." }

A startup refusal is read on the container’s error output: a message, no stack trace, no open port, and an exit code of 1. No incomplete configuration falls back on degraded behavior.

Cause
The administration account’s key is missing, empty or too weak, in the profile operated by the vendor.
The database address is missing, or it carries an encryption parameter that the code refuses to let decide in its place.
The deployment license is missing, unreadable, badly signed, or expired for longer than its grace period. The gateway refuses rather than serve a fleet without a valid license. This refusal exists only in the profile installed at the customer’s site: the profile operated by the vendor carries no deployment license.
The account the gateway used to connect to its database can rewrite or erase billed consumption or audit logs, which is the case for the owner account. It refuses to start rather than produce billing that its own producer can rewrite. Same refusal when the database cannot answer the question, because the migration that creates the service roles has not been applied: not knowing is not a green light.
The declared enterprise proxy is not a usable URL, or the store of internal authorities is unreadable.
The service certificate, the key that goes with it, the database’s authority or the cap on a request’s duration are incomplete or out of bounds.
The declared documentation directory is unreadable, does not carry the identity card that every archive brings along, does not declare its version and path, or declares a path this gateway does not serve. The gateway refuses rather than serve documentation whose version it does not know or whose links would all be broken.
The agent command launcher is named without being offered, or it is named without the working directory it requires.
The gateway does not know which organization’s policy it serves to workstations. It refuses rather than assume: an assumed organization would make it answer “nothing is restricted” to a whole fleet of workstations, with nothing looking broken.

The names of the variables cited by these messages are on the page Gateway environment variables.

Role assignment, revoking a subject and installing a policy are done through administration commands and through the console. The console has its own page, Administration console, and the everyday gestures on accounts and keys are described by Track and correct access from the console. The administration commands themselves have no page on this site. The tables where all of this is stored are described by Gateway database tables.