@knowttl/artium-axi 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,51 +1,76 @@
1
- <h1 align="center">artium-axi</h1>
1
+ # artium-axi
2
2
 
3
- <p align="center">
4
- <img alt="Status" src="https://img.shields.io/badge/status-under%20construction-orange?style=flat-square" />
5
- <img alt="Verified platform" src="https://img.shields.io/badge/verified%20platform-Linux-blue?style=flat-square" />
6
- <a href="https://github.com/kunchenguid/axi"><img alt="AXI" src="https://img.shields.io/badge/AXI-Agent%20eXperience%20Interface-green?style=flat-square" /></a>
7
- </p>
3
+ Managed command-line tools for agents and the humans running them, with one sign-in, role-based access and server-held service credentials.
8
4
 
9
- Managed command-line tools for agents, behind one artium sign-in.
5
+ [![License: MIT](https://img.shields.io/github/license/knowttl/artium-axi)](LICENSE)
6
+ [![npm](https://img.shields.io/npm/v/@knowttl/artium-axi)](https://www.npmjs.com/package/@knowttl/artium-axi)
7
+ [![Node](https://img.shields.io/badge/Node-%3E%3D24.11.0-green)](package.json)
8
+ [![Release provenance](https://img.shields.io/badge/release-provenance-blue)](https://github.com/knowttl/artium-axi/attestations)
10
9
 
11
- artium-axi packages a server and CLI that give users role-based access to pinned upstream tools.
12
- The published Graph and Azure releases in [the upstream pins](tools/package.json) include their upstream live-test fixes.
13
- Administrators manage accounts, roles, encrypted service credentials and audit records through a browser.
14
- The client follows AXI (Agent eXperience Interface) conventions for discovery, help and structured errors.
10
+ [Quickstart](#quickstart) • [Use with your agent](#use-with-your-agent) • [Features](#features) • [Safety](#safety) • [Configuration](#configuration) • [Commands](#commands)
15
11
 
16
- **Status: under construction.**
17
- Falcon, Vectra, Azure, Graph, LDAP, Azure DevOps and AWX are wired into the production server entry point.
18
- See the [evidence ledger](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/evidence-ledger.md) for the acceptance boundaries.
19
-
20
- ## Agent Ergonomics
21
-
22
- - Running without arguments shows identity, roles, available tools, cached health and pinned versions.
23
- - Tool lists show cached health, pinned versions and write-access status and suggest a detail view and first call.
24
- - Empty lists explain why no enabled tool is available and direct you to an administrator.
25
- - Local help works before sign-in and includes usage, purpose, flags and an example.
26
- - Artium errors use TOON on stdout; upstream calls preserve separate stdout, stderr and exit status.
27
- - Managed skills support Claude Code, Codex, OpenCode and Pi, with an optional Claude Code session hook.
12
+ ```mermaid
13
+ flowchart LR
14
+ Agent[Agent or human] --> CLI[Artium CLI]
15
+ CLI -->|HTTPS and Artium identity| Server[Artium server]
16
+ Admin[Administrator] -->|Browser administration| Server
17
+ Server --> Store[Encrypted credentials and audit]
18
+ Server --> Runner[Bounded tool runner]
19
+ Runner --> APIs[Vendor APIs]
20
+ ```
28
21
 
29
- ## Quick Start
22
+ ## Why this exists
30
23
 
31
- For a new server, follow [Set up a host](#set-up-a-host) first.
32
- For an existing server, obtain its trusted HTTPS URL and an account from its administrator, then continue below.
33
- The Linux client requires Node **24.11 or later**, curl and sha256sum on `PATH`.
34
- Windows and macOS execution, token storage and actual agent host loading remain unverified.
24
+ Separate vendor CLIs require separate credentials and access controls on every agent host.
25
+ Artium runs pinned tools on a shared server, checks each user's roles and supplies the service credential after audited admission.
26
+ Agents keep a command-line interface with TOON discovery rather than implementing each vendor's REST authentication or an MCP integration.
35
27
 
36
- ### Download and first call
28
+ ## Features
37
29
 
38
- Set the trusted HTTPS server URL before downloading:
30
+ - **Access:** local or browser SSO sign-in, role grants and session revocation.
31
+ - **Credentials:** encrypted shared service identities, private per-call profiles and credential tests.
32
+ - **Discovery:** available tools, cached health, pinned versions and contextual first-call suggestions.
33
+ - **Agent setup:** managed skills for Claude Code, Codex, OpenCode and Pi; optional Claude Code session hook.
34
+ - **Audit:** authentication, administration and tool-call records with filtered CSV/JSON-lines export.
35
+ - **Limits:** reviewed command inventories, write switches, bounded runtime, output and concurrency.
39
36
 
40
- ```sh
41
- export ARTIUM_AXI_URL='https://artium.example.com'
42
- ```
43
-
44
- For a private CA, set `ARTIUM_AXI_CA_FILE` to its readable PEM file and add `--cacert "$ARTIUM_AXI_CA_FILE"` to **both** curl commands below.
45
- Keep certificate verification enabled.
46
- The bundle and checksum must come from the trusted server; the checksum detects corruption and mixed releases, not an untrusted server.
37
+ ### Supported pinned tools
38
+ | Tool | Version | Managed access |
39
+ | --- | --- | --- |
40
+ | Falcon | 0.5.0 | Read-only API client |
41
+ | Vectra | 0.1.7 | Token or OAuth; optional allow-listed writes |
42
+ | Azure | 0.1.10 | Application identity and resource-token broker |
43
+ | Microsoft Graph | 0.1.10 | Application identity; optional allow-listed writes |
44
+ | LDAP | 0.2.0 | Verified TLS simple bind; read-only |
45
+ | Azure DevOps | 0.4.6 | PAT or application identity |
46
+ | AWX | 0.1.7 | Pasted token or one-time password sign-in; optional operational writes |
47
+
48
+ [Package pins](tools/package.json), [Falcon source pin](tools/falcon-source.json) and [reviewed inventories](tools/inventories) define the supported boundary.
49
+
50
+ ## Quickstart
51
+
52
+ ### Deploy a server with your agent
53
+ Give this prompt to the agent helping you administer the server:
54
+
55
+ > Deploy artium-axi on my Linux host.
56
+ > Check Docker/Compose, host capacity, ports, DNS and the HTTPS/TLS plan first.
57
+ > Use the repository's Compose file to build the server, or a published image only after verifying its release digest and provenance as described in the runbook.
58
+ > Generate an exactly 32-byte random master key into a protected file, make it readable by container UID 10001, and keep an offline escrow copy separate from database backups.
59
+ > Create the first administrator through the documented first-start password-file bootstrap, change its temporary password and remove bootstrap inputs.
60
+ > Configure tool credentials through the administrator UI, test each credential, enable the intended tools and grant roles.
61
+ > Run liveness, readiness and a permitted read for each enabled tool; report results and remaining limits without secrets.
62
+ > Never ask me to paste passwords, tokens or keys into chat or command arguments.
63
+ > Use hidden prompts, protected stdin or files with safe permissions for secrets.
64
+ > Follow docs/admin-guide.md, docs/tool-credentials.md and docs/runbook.md for the exact steps.
65
+
66
+ For manual deployment, follow the [administrator guide](docs/admin-guide.md#set-up-a-host).
67
+
68
+ ### Verified client
69
+ Use Linux with Node **24.11.0+**, curl and sha256sum, and obtain the trusted HTTPS URL and account from your administrator.
70
+ For a private CA, set `ARTIUM_AXI_CA_FILE` to a readable PEM file and add `--cacert "$ARTIUM_AXI_CA_FILE"` to both curl commands.
47
71
 
48
72
  ```sh
73
+ export ARTIUM_AXI_URL='https://artium.example.test'
49
74
  mkdir -p "$HOME/.local/bin"
50
75
  cd "$HOME/.local/bin"
51
76
  curl --fail --output artium-axi.mjs "$ARTIUM_AXI_URL/cli/artium-axi.mjs" &&
@@ -57,870 +82,168 @@ rm artium-axi.mjs.sha256
57
82
  export PATH="$HOME/.local/bin:$PATH"
58
83
  ```
59
84
 
60
- **Stop if either download or checksum verification fails.**
61
- Do not launch the downloaded file after a failure.
62
- The executable is a standalone Node bundle; it needs no npm install or sibling assets.
63
-
64
- For an SSO account, follow [CLI SSO sign-in](#sign-in-settings), then continue with tool discovery below.
65
- For a local account, sign in using the hidden terminal password prompt, replacing the synthetic username with your account:
85
+ Stop if a download or checksum fails.
86
+ The checksum detects corruption and mixed releases; trust still comes from the HTTPS server.
66
87
 
67
88
  ```sh
68
89
  artium-axi login --username synthetic-user
69
- ```
70
-
71
- If login reports `PASSWORD_CHANGE_REQUIRED`, change the temporary password and sign in again:
72
-
73
- ```sh
74
- artium-axi passwd
75
- artium-axi login --username synthetic-user
76
- ```
77
-
78
- Discover the tools granted to your account:
79
-
80
- ```sh
81
- artium-axi
82
90
  artium-axi tools
83
91
  artium-axi tools show falcon-axi
84
92
  artium-axi falcon-axi detection list
85
93
  ```
86
94
 
87
- The Falcon example requires an enabled Falcon tool and a role granting access to it.
88
- Choose your first call from the example shown for an available tool.
89
-
90
- ### Skill installation
95
+ Replace the synthetic username with your account; login uses a hidden terminal password prompt.
96
+ For `PASSWORD_CHANGE_REQUIRED`, run `artium-axi passwd`, then log in again.
97
+ For SSO, use `artium-axi login --sso` and approve only the browser code matching your own terminal.
98
+ The Falcon read requires an enabled tool, a role grant and API permissions; choose the example from an available tool's detail view.
91
99
 
92
- Install the base skill and a skill for every tool granted to your signed-in account:
100
+ With no enabled tools granted, `artium-axi tools` succeeds with:
93
101
 
94
- ```sh
95
- artium-axi setup --host claude --hook
102
+ ```text
103
+ tools: 0 available
104
+ reason: No enabled runtime tool is available through your assigned roles.
105
+ contact: Ask an administrator to check your role assignments and enabled tools.
106
+ next[1]:
107
+ - artium-axi whoami
96
108
  ```
97
109
 
98
- Use `--host codex`, `--host opencode` or `--host pi` without `--hook` for those hosts.
99
- See [host paths and configuration overrides](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/verification-s45.md) for installation locations.
100
- Setup requires the configured server URL and an authenticated account.
101
- It fetches reviewed adaptations of the server's pinned upstream skills; command examples run through `artium-axi <tool>` using Artium-managed credentials.
102
- Skills include granted tools that are disabled; running those tools still returns `TOOL_DISABLED`.
103
- Only Claude Code supports the optional `SessionStart` hook, which runs `tools` to supply session context.
104
- Unsupported hosts or hooks are refused before files are written.
105
-
106
- Setup preserves unrelated settings and hooks and leaves unchanged managed files alone.
107
- It refuses to replace an edited or unmanaged skill unless `--force` is explicit.
108
- Setup checks every skill and hook setting before writing; a refusal leaves the installation unchanged.
109
- Re-run setup to add newly granted tools.
110
- Artium-managed skills for tools no longer granted are retained and reported, not deleted.
111
- Unmanaged standalone skills outside the current grants are left untouched and unreported.
112
- Output lists one installed, unchanged or retained row per skill.
113
- Keep the bundle at its installed path; rerun setup if it moves so recorded invocations are repaired.
114
- See [host verification](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/verification-s45.md) for recorded discovery checks and outstanding acceptance.
115
-
116
- ## Other ways to install
117
-
118
- ### npm client
119
-
120
- Downloading the client and checksum from your server remains the recommended installation path because it supplies the matching version.
121
- As an alternative, install the client CLI and its embedded skill from npm with Node.js 24.11.0 or newer:
110
+ ### npm client alternative
111
+ The server download supplies its matching client; npm is an alternative client-only distribution.
122
112
 
123
113
  ```sh
124
114
  npm install -g @knowttl/artium-axi
125
- export ARTIUM_AXI_URL='https://artium.example'
115
+ export ARTIUM_AXI_URL='https://artium.example.test'
126
116
  artium-axi login --username synthetic-user
127
- artium-axi setup --host codex
128
117
  ```
129
118
 
130
- The npm package contains no server or upstream executables and needs no runtime npm dependencies.
131
- Login warns when client and server versions differ and continues signing in.
132
- Download the matching client and checksum from your server, or install its version with `npm install -g @knowttl/artium-axi@<server-version>`.
133
- Older servers without a version response header cannot supply this warning.
134
- A successful login does not bypass the [minimum CLI version requirements](src/shared/api.ts) for subsequent API calls.
135
-
136
- ### Set up a host
137
-
138
- Give the setup agent the Linux host access, intended HTTPS hostname, DNS and certificate provisioning method, private CA bundle if applicable, and the protected data and backup locations.
139
- Also supply the first administrator's username and temporary password through protected input, a master-key custody decision, and credentials for each tool you want enabled from [Tool credentials](#tool-credentials).
140
- Upstream accounts are shared server-side service identities; users sign in with their own [artium accounts](#sign-in-settings).
141
-
142
- 1. **Prepare the host.**
143
- Install Git and Docker with Compose and reserve HTTPS port 443 for the reverse proxy.
144
- The image supplies Node, Python and the pinned tools; see [Build from source](#build-from-source) for the source toolchain.
145
- Allow package and image downloads during the build and runtime access to the enabled tools' upstream APIs and identity endpoints.
146
- See [runbook prerequisites](docs/runbook.md#scope-and-prerequisites) for the runtime limits, writable data directory and UID 10001 ownership, including rootless UID mapping.
147
-
148
- 2. **Obtain the source and build the image.**
149
- Run from the checkout root:
150
-
151
- ```sh
152
- git clone https://github.com/knowttl/artium-axi.git
153
- cd artium-axi
154
- docker compose -f compose.example.yaml build
155
- ```
156
-
157
- Record the resulting immutable image identity for backups and rollback as described in the [runbook](docs/runbook.md#backup-restore-and-upgrade-rollback).
158
-
159
- 3. **Prepare the master key and bootstrap administrator before starting.**
160
- Place an owner-generated cryptographically random key containing exactly 32 raw bytes at `private/artium_master_key` and the temporary administrator password at `private/artium_bootstrap_password`, with no added newline.
161
- Use the [password rules](#security-and-acceptance-boundaries) and [key custody guidance](docs/runbook.md#backup-restore-and-upgrade-rollback).
162
- Follow the [secret ownership instructions](docs/runbook.md#scope-and-prerequisites) so both files are readable by container UID 10001 and protected from other users.
163
- In [compose.example.yaml](compose.example.yaml), uncomment both first-start environment settings and both bootstrap-password secret entries, replacing `synthetic-admin` with your chosen username.
164
- The master key alone cannot bootstrap a new store.
165
- See [first-administrator setup](docs/runbook.md#first-administrator-and-offline-recovery) for the empty-store requirement and startup refusals.
166
-
167
- 4. **Configure HTTPS.**
168
- Follow the [runbook proxy example](docs/runbook.md#proxy-and-certificate-trust), including its static proxy IP, matching `ARTIUM_AXI_TRUSTED_PROXIES`, TLS mounts and forwarding-header replacement.
169
- Save your Compose override as `compose.proxy.yaml` and provision its nginx configuration and certificates before starting.
170
- Keep the HTTP listener inaccessible to clients and select an unused proxy subnet.
171
-
172
- 5. **Start and check the server.**
173
- With that override prepared, run:
174
-
175
- ```sh
176
- docker compose -f compose.example.yaml -f compose.proxy.yaml config --quiet
177
- docker compose -f compose.example.yaml -f compose.proxy.yaml up -d
178
- docker compose -f compose.example.yaml -f compose.proxy.yaml ps
179
- ```
180
-
181
- Require a healthy Artium service, then set `ARTIUM_AXI_URL` to the trusted HTTPS origin and run the [HTTPS liveness and readiness checks](docs/runbook.md#roles-credentials-and-health).
182
- Both checks must return `status: ok`; they check the local server, not upstream credentials.
183
- If startup fails, inspect service logs and resolve the reported configuration or store error before continuing.
184
-
185
- 6. **Complete the first login.**
186
- Open `https://<your-artium-host>/login`, enter the bootstrap account, change its temporary password at `/password`, and sign in again.
187
- Remove the first-start environment settings and bootstrap-password secret entries from Compose after the administrator is created, remove the bootstrap-password file from its provisioning location, and recreate the service with the same `up -d` command.
188
- Keep the master-key file and persistent data volume for subsequent starts.
189
- Startup also saves the key beside the database, so protect the entire data volume as explained in [server custody](#server-settings-and-custody).
190
-
191
- 7. **Configure tools and user access.**
192
- Follow [Tool credentials](#tool-credentials) to save and test each credential, then follow the [activation requirements](#browser-administration) before enabling the tool at `/admin/tools`.
193
- Create a role at `/admin/roles`, grant it the enabled tools, create local users at `/admin`, and assign that role to them.
194
- Assign a tool role to your administrator too if that account will run CLI calls; administrator capability alone grants no tool access.
195
- Finish with [Download and first call](#download-and-first-call) and [Skill installation](#skill-installation) on each agent host.
196
-
197
- Recovery, rotation, backups, retention and upgrades remain in the [operations runbook](docs/runbook.md).
198
-
199
- ### Tool credentials
200
-
201
- Configure only the tools you intend to use.
202
- At `/admin/tools`, open the tool, save its credential, then use **Test credential** and follow the [activation requirements](#browser-administration) before enabling it.
203
- The [credential standard](docs/credential-standard.md#9-hosted-contract-artium-axi) owns profile injection and secret handling; [browser administration](#browser-administration) explains editor inputs, saving and health behavior.
204
-
205
- | Tool | Information to obtain | Fixed Artium credential test |
206
- | --- | --- | --- |
207
- | Falcon (`falcon-axi`) | Falcon API client ID, client secret, cloud region, optional Flight Control member CID. | `auth status`, followed by a permitted detection read to confirm API access. |
208
- | Vectra (`vectra-axi`) | HTTPS origin, QUX/RUX deployment kind and API version, personal token or OAuth client ID and secret, optional private CA PEM. | `health list`; grant access to health reads as well as your intended data. |
209
- | Azure (`az-axi`) | Entra tenant ID, application client ID, client secret or certificate private key and SHA-256 thumbprint, subscription IDs and optional workspace mapping. | `account list`; data-plane roles need their own permitted reads. |
210
- | Microsoft Graph (`mg-axi`) | Entra tenant ID, application client ID, client secret or certificate private key and SHA-256 thumbprint, administrator-consented Graph application permissions. | `entra user list --limit 1`; other domains need their own permissions. |
211
- | LDAP (`ldap-axi`) | Verified LDAPS or StartTLS URL, read-only bind identity and password, optional search base and private CA PEM. | `auth status`; binds once and reports the selected identity. |
212
- | Azure DevOps (`ado-axi`) | Organization, optional default project and either a PAT or tenant ID, client ID and client secret. | `project list --limit 1`. |
213
- | AWX (`awx-axi`) | Controller HTTPS origin and an existing personal access token. | `job list --limit 1`; job read permissions are required. |
214
-
215
- #### Falcon
216
-
217
- In the Falcon console, open **Support and resources > API clients and keys** and create a dedicated API client.
218
- Copy its client ID and secret and record its cloud region: `us-1`, `us-2`, `eu-1` or `us-gov-1`.
219
- At `/admin/tools/falcon-axi`, enter `clientId`, `clientSecret` and `region`, with `memberCid` only when targeting a Flight Control member tenant.
220
- Grant `Alerts:read` for detection reads, including the first-call example.
221
- Grant additional scopes only for the domains you use, following the pinned [API client permission matrix](https://github.com/knowttl/falcon-axi/blob/v0.5.0/README.md#api-client-permissions) and its offline `scopes` command.
222
- For example, account reads need `Assets:read`, while CVE reads need `Vulnerabilities (Falcon Intelligence):read`, distinct from Spotlight vulnerability access.
223
- NG-SIEM search requires `NGSIEM:write`; Identity Protection directory/timeline queries require `Identity Protection GraphQL:write` plus the documented read scopes, even though those queries read data.
224
- These are optional domain requirements and do not justify granting other write or response scopes.
225
- The pinned tool does not change hosts, detections, policies or identities and exposes no arbitrary REST or GraphQL requests.
226
- Starting and stopping NG-SIEM search jobs are its only tenant-side effects; these investigation operations remain available regardless of the saved write switch.
227
- Falcon's fixed `auth status` test reports local credential resolution, so also run `artium-axi falcon-axi detection list --limit 1` after enabling and granting the tool.
228
-
229
- #### Vectra
230
-
231
- Obtain the deployment's HTTPS origin; see [credential editor guidance](#browser-administration) for accepted input.
232
- For QUX, select `kind=qux`, `apiVersion=2.5` and either `auth=token` with `token`, or `auth=oauth` with `clientId` and `clientSecret`.
233
- QUX OAuth requires appliance release 9.1 or later; `applianceRelease` is optional release metadata.
234
- For RUX, select `kind=rux`, `apiVersion=3.4`, `auth=oauth`, `clientId` and `clientSecret`; leave `applianceRelease` blank.
235
- Create a QUX personal token under **My Profile** using a local account, or have a Vectra administrator create an OAuth API client under **Manage > API Clients** and record the displayed ID and secret.
236
- Tokens inherit their user's rights and clients inherit their assigned role; grant read access to health and the Hosts, Accounts, Detections or other areas you need.
237
- See [Vectra's credential issuance guidance](https://github.com/vectranetworks/vectraautomatedresponse#getting-a-vectra-api-token-for-vectra-detect-api-v2) and the pinned [Vectra configuration contract](https://github.com/knowttl/vectra-axi/tree/v0.1.7#configuration) for deployment-specific requirements.
238
- For a credential-specific private CA, paste its PEM contents into `caBundle`; enter no server file path.
239
- For shared trust across tools, follow the [private CA runbook](docs/runbook.md#tls-inspection-and-private-upstream-cas).
240
- Keep Native settings empty for read-only use; optional writes need the native operation allowlist and upstream permissions.
241
- Save, run **Test credential**, enable and grant the tool, then run `artium-axi vectra-axi detection list --limit 1` to check the intended read domain.
242
-
243
- #### Entra application registration for Azure and Graph
244
-
245
- In the [Entra admin center](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app), open **App registrations > New registration** and register an application in your organization directory.
246
- Record the **Directory (tenant) ID** as `tenantId` and **Application (client) ID** as `clientId` from Overview.
247
- Under **Certificates & secrets**, create a client secret and copy its **Value**, not its secret ID, before leaving the page.
248
- Alternatively upload a public certificate and retain its matching PEM private key and 64-hex-digit SHA-256 certificate thumbprint.
249
- No interactive user login or redirect URI is needed for these hosted application credentials.
250
- Azure RBAC roles and Graph API application permissions are separate grants; configuring one does not grant the other.
251
- You can use separate app registrations for the two tools or enter the same approved application identity separately in each editor.
252
-
253
- #### Azure
254
-
255
- In the Azure portal, select each subscription or narrower resource scope, open **Access control (IAM) > Add role assignment**, select the role, and assign it to the registered application's service principal.
256
- Have an administrator authorized to assign roles perform this step.
257
-
258
- | Role | Use |
259
- | --- | --- |
260
- | `Reader` | ARM inventory and metadata at the intended subscription/resource scope. |
261
- | `Log Analytics Reader` | Workspace query access when granting workspace-specific log reads. |
262
- | `Storage Blob Data Reader` | Blob data-plane reads; ARM `Reader` and `Contributor` alone do not supply these. |
263
- | `Key Vault Reader` | Secret, key and certificate metadata on RBAC-mode vaults, without secret values. |
264
- | `AcrPull` | Registry pull/catalogue access on RBAC-only registries. Not honored on ABAC-enabled registries. |
265
- | `Container Registry Repository Catalog Lister` | Catalogue listing on ABAC-enabled registries; lists all repositories and does not support ABAC conditions. |
266
- | `Container Registry Repository Reader` | Image, tag and metadata reads on ABAC-enabled registries; optional ABAC conditions restrict repositories. Does not grant catalogue listing. |
267
- | `Contributor` | Optional ARM writes at the intended scope, only when writes are wanted; this does not assign roles or grant blob/vault data-plane writes. |
268
-
269
- Check the registry's **Settings > Properties > Role assignment permissions mode** before choosing registry roles; see [Microsoft's registry permission guidance](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-rbac-abac-repository-permissions).
270
- On ABAC-enabled registries, ARM `Reader` and `Contributor` grant control-plane access only, so assign the catalogue and repository roles above for the reads you need.
271
- Access-policy-mode vaults require corresponding vault access policies instead of the RBAC-mode role.
272
-
273
- At `/admin/tools/az-axi`, choose authentication and enter the source identity in the guided credential fields.
274
- Save subscriptions and write settings separately in Native settings.
275
- The equivalent complete replacement API input has this shape, replacing every placeholder:
276
-
277
- ```json
278
- {
279
- "auth": "secret",
280
- "tenantId": "<directory-tenant-UUID>",
281
- "clientId": "<application-client-UUID>",
282
- "clientSecret": "<client-secret-value>",
283
- "subscriptions": ["<subscription-UUID>"],
284
- "allowWrites": false
285
- }
286
- ```
287
-
288
- For certificate authentication, set `auth` to `certificate` and replace `clientSecret` with `privateKey` and `thumbprintSha256`.
289
- Optionally add `workspaces` as a JSON object mapping friendly names to Log Analytics workspace customer-ID UUIDs, obtained from the workspace Overview page; these are not ARM resource IDs.
290
- Artium mints and injects resource-specific tokens, so supply the source identity rather than an access token or upstream token-profile JSON.
291
- Save, run **Test credential**, enable and grant the tool, then run `artium-axi az-axi account list`.
292
- Test each needed data-plane read separately using the enabled tool's help; a successful subscription list proves no blob, vault or registry access.
293
- For registry catalogue access, run `artium-axi az-axi acr repository list --name <registry>`; test any needed image, tag or metadata reads separately because catalogue listing does not grant repository reads on ABAC-enabled registries.
294
- Keep `allowWrites` false unless writes are wanted and the corresponding Azure roles are approved.
295
-
296
- #### Microsoft Graph
297
-
298
- On the app registration, open **API permissions > Add a permission > Microsoft Graph > Application permissions**.
299
- Add `User.Read.All` for Artium's credential test and first user read, then have an authorized administrator [grant tenant-wide admin consent](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/grant-admin-consent).
300
- Add only the application permissions for the additional command families you intend to use, and grant admin consent again after changes.
301
- Delegated permissions and interactive `User.Read` consent do not authorize this application flow.
302
-
303
- | Optional read area | Graph application permissions |
304
- | --- | --- |
305
- | Groups and memberships | `GroupMember.Read.All`; `Group.Read.All` for richer group properties, `Member.Read.Hidden` for hidden memberships. |
306
- | Applications, service principals and application consent | `Application.Read.All` |
307
- | Devices | `Device.Read.All` |
308
- | Organization metadata | `Organization.Read.All` |
309
- | Directory roles | `RoleManagement.Read.Directory` |
310
- | Conditional Access and policy reads | `Policy.Read.All` |
311
- | Sign-ins, directory audits and authentication registration reports | `AuditLog.Read.All`; provisioning logs also need `Directory.Read.All`. |
312
- | Risky users and service principals | `IdentityRiskyUser.Read.All`, `IdentityRiskyServicePrincipal.Read.All`, according to the command. |
313
- | Entitlement management | `EntitlementManagement.Read.All` |
314
- | User authentication methods | `UserAuthenticationMethod.Read.All` |
315
- | Access reviews | `AccessReview.Read.All` |
316
- | Directory role eligibility and assignment schedules | `RoleEligibilitySchedule.Read.Directory`, `RoleAssignmentSchedule.Read.Directory` |
317
- | Privileged group eligibility | `PrivilegedEligibilitySchedule.Read.AzureADGroup` |
318
- | Cross-tenant information | `CrossTenantInformation.ReadBasic.All` |
319
- | Certificate authentication PKI | `PublicKeyInfrastructure.Read.All` |
320
- | Multitenant organization | `MultiTenantOrganization.ReadBasic.All` or `MultiTenantOrganization.Read.All`, according to the operation |
321
- | Identity providers | `IdentityProvider.Read.All` |
322
- | Lifecycle workflows | `LifecycleWorkflows.Read.All` |
323
-
324
- For other domains, use the pinned [Graph access and licence guidance](https://github.com/knowttl/mg-axi/blob/v0.1.10/docs/graph-coverage.md) and the command's permission requirements rather than granting every permission.
325
- Licences still apply: PIM and risk/governance features can fail despite consent, and some commands support only delegated identities.
326
- Do not add `User.Export.All` just to make a read-only setup pass; data-policy export is a write-class permission.
327
-
328
- In the Graph credential form, choose `mode=application`, `cloud=commercial`, `auth=client-secret`, then enter `tenantId`, `clientId` and the secret value in `clientSecret`.
329
- For a certificate, choose `auth=certificate`, enter the PEM in `privateKey` and its SHA-256 thumbprint in `thumbprintSha256`, leaving `clientSecret` blank.
330
- Leave `allowDeviceCode`, `preview`, `sensitiveAreas` and `writes` at their defaults for the initial read-only setup.
331
- Save, run **Test credential**, follow the [activation requirements](#browser-administration), enable and grant the tool, then run `artium-axi mg-axi entra user list --limit 1`.
332
- Hosted application mode acquires tokens silently; do not run upstream `auth login` or supply `--scopes` through Artium.
333
- See the [evidence ledger](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/evidence-ledger.md) for recorded local and owner live acceptance; credential setup instructions do not establish acceptance for a new host or every upstream operation.
334
-
335
- #### LDAP
336
-
337
- Artium uses the [pinned npm release](tools/package.json) of `@knowttl/ldap-axi` with stored simple-bind credentials, encrypted by the same credential store as the other tools.
338
- The user's ambient Kerberos ticket belongs to their local login and is unavailable inside Artium's server-side isolated runner.
339
- Artium therefore requires `auth=simple`; it does not accept a keytab or manage Kerberos ticket acquisition and renewal.
340
- This keeps the directory identity explicit and its password rotation within the existing credential replacement flow.
341
- The native Kerberos provider and its installation script are unnecessary for this authentication mode and remain disabled.
342
-
343
- Obtain a dedicated directory identity with read access only, its bind DN and password, and a directory URL whose certificate can be verified.
344
- At `/admin/tools/ldap-axi`, enter `url`, choose `auth=simple`, and enter `bindDn` and the password value in `bindPassword`.
345
- Use `ldaps://<directory-host>:636` with `startTls` left at the default (unset) or explicitly `false`, or `ldap://<directory-host>:389` with `startTls=true`.
346
- Saving an `ldaps://` URL with `startTls=true` is rejected with `INVALID_INPUT` and the message `startTls must be false for this URL.`
347
- Plaintext simple bind, anonymous authentication, disabled certificate verification and caller-supplied connection or credential overrides are refused.
348
- For a credential-specific private CA, supply its PEM contents in `caFile`, not a server file path.
349
- For shared trust across tools, follow the [private CA runbook](docs/runbook.md#tls-inspection-and-private-upstream-cas).
350
- The multi-line `caFile` editor preserves newlines through saving and private CA file materialization for each call.
351
- Artium's CLI has no credential-save command.
352
- Optional `base` limits the search context; otherwise the pinned tool discovers the directory's default naming context.
353
- Optional `pageSize` is an integer from 1 to 1000, and `tlsMaxVersion=1.2` supports TLS 1.2-only endpoints while retaining verification.
354
-
355
- Enter the password itself in the form, never a SecretRef or password-file path.
356
- Save, run **Test credential**, enable the tool, grant it to a role, then run `artium-axi ldap-axi user list --limit 1` to check directory read permissions.
357
- **Test credential** runs `auth status`, which performs one bind; failed credentials can count toward directory account lockout limits.
358
- LDAP is read-only by design and has no editable native write settings.
359
- LDAP 0.2.0 adds `computer list`, `computer show <identifier-or-dn>` and `server` reads through the same managed identity.
360
- Computer reads use AD machine accounts or the upstream's stated LDAPv3 device fallback; `server` reports advertised rootDSE capabilities and limits.
361
- The [LDAP inventory](tools/inventories/ldap-axi.json) owns the supported commands, blocked overrides and resource requirements.
362
- Local fake-directory and offline profile checks do not establish live directory acceptance.
363
-
364
- #### Azure DevOps
365
-
366
- Artium uses the [pinned](tools/package.json) `@jeffreyhaen/ado-axi` release without upstream modifications.
367
- At `/admin/tools/ado-axi`, enter `org`, optional `project`, choose `auth=pat`, and paste the PAT itself into `token`.
368
- Organization-root URLs such as `https://dev.azure.com/<org>` and `https://<org>.visualstudio.com` normalize to the organization name.
369
- Artium encrypts the PAT in its credential store and injects it through a private per-call profile and environment variable.
370
- Do not enter a SecretRef or environment-variable name.
371
- Create a dedicated PAT scoped to the organization with Work Items, Code and Build read permissions as needed for the commands you use.
372
- Grant corresponding read-write permissions only for intended mutations; a write switch never grants Azure DevOps permissions.
373
- For service principal authentication, choose `auth=client-secret` and enter `tenantId`, `clientId` and `clientSecret` instead of `token`.
374
- Add the service principal as a user in the Azure DevOps organization, in the organization's Entra tenant, and grant the required project permissions before testing.
375
- Artium acquires and caches an Azure DevOps access token with client credentials and supplies it through a restricted per-call `az` stand-in.
376
- The stand-in answers only the pinned tool's Azure DevOps token request; no Azure CLI sign-in or device flow is used.
377
- Save, run **Test credential**, enable the tool, grant it to a role, then run `artium-axi ado-axi project list --limit 1`.
378
-
379
- Writes are off by default; follow [write-access administration](docs/runbook.md#roles-credentials-and-health) to enable them.
380
- Artium classifies every command using the reviewed [ADO inventory](tools/inventories/ado-axi.json), which binds the routing review to upstream source digests.
381
- Artium manages `--org`, `--profile` and `--config`; those overrides and the top-level `config` and `update` commands are refused.
382
- Use `--project` to select another project within the managed organization.
383
- The `api` command accepts relative paths and GET only, even when writes are enabled; body flags and absolute URLs are refused.
384
- All commands refuse repeated flags, stdin and files.
385
- Use `pipeline watch --timeout 50` or less to stay within the runner's call timeout.
386
- Writes are journaled by Artium only; see [audit action classification](#audit-screen-and-api).
387
- For an interrupted write, run the returned read-back command and follow its inspection guidance before retrying.
388
- Local fake-service checks do not establish live organization acceptance.
389
-
390
- #### AWX
391
-
392
- Artium bundles the [pinned](tools/package.json) `awx-axi` package without upstream modifications.
393
- At `/admin/tools/awx-axi`, enter the controller HTTPS `origin` and paste an existing personal access token into `token`.
394
- Enter the token itself, never a SecretRef, environment-variable name, password or file path.
395
- Artium encrypts the token and injects a SecretRef through its private per-call profile; it does not mint or revoke AWX tokens.
396
- Save, run **Test credential**, enable the tool and grant it to a role, then run `artium-axi awx-axi job list --limit 1`.
397
- **Test credential** reads one job using the managed token and reports structured authentication, network and TLS diagnostics.
398
- For a private certificate, inspect and trust it through the tool page; trust is scoped to the saved credential and host.
399
- HTTP and TLS-verification bypasses are refused.
400
-
401
- Writes are off by default.
402
- The native setting `{"allowWrites": true}` permits only operational writes, which still require upstream `--confirm`: launching, canceling or relaunching runs, approving or denying workflow approvals, project and inventory-source syncs, and notification-template tests.
403
- Configuration writes, deletes and security writes are always blocked, including resource creation and editing, associations, role grants and token operations.
404
- Artium never enables AWX's separate configuration, deletion or security write gates.
405
- Token permissions remain an additional AWX-side limit; the write switch does not grant AWX permissions.
406
- The generated [AWX inventory](tools/inventories/awx-axi.json) classifies every command and records the reviewed upstream source digests.
407
- Artium manages origin, TLS and credential selectors, and refuses standalone auth login/logout, setup, config, profile and update commands.
408
- Stdin, file uploads, server file paths and `@file` values are unsupported; use inline non-secret launch parameters.
409
- Use `job watch --timeout 50` or less to stay within the runner timeout.
410
- For an interrupted write, inspect current state using the returned read-back guidance before retrying.
411
- Local fake-service checks do not establish live controller acceptance.
119
+ Login warns about version differences; minimum server API requirements still apply.
120
+ Install `@knowttl/artium-axi@<server-version>` or download from the server to match it.
412
121
 
413
122
  ### Build from source
414
-
415
- The source toolchain requires Node **24.11 or later** and **pnpm 10.22.0**.
416
- From the repository root:
123
+ Use Node 24.11.0+, pnpm 10.22.0, OpenSSL, Python 3, curl and sha256sum on Linux.
417
124
 
418
125
  ```sh
126
+ git clone https://github.com/knowttl/artium-axi.git
127
+ cd artium-axi
419
128
  pnpm install --frozen-lockfile
420
129
  pnpm build
421
130
  node dist/cli/artium-axi.mjs --help
422
131
  ```
423
132
 
424
- The build produces the standalone `dist/cli/artium-axi.mjs`.
425
- Set `ARTIUM_AXI_URL` and use the same login and discovery commands with `node dist/cli/artium-axi.mjs` in place of `artium-axi`.
426
- After signing in, run `node dist/cli/artium-axi.mjs setup --host codex` to install your granted skills.
427
- The root package remains private for server development; `pnpm build:npm` stages the separate public client package in `dist/npm` using the root package version.
428
- Run `npm pack --dry-run ./dist/npm` to inspect the client tarball before release.
429
- Only the bundled CLI, skill, README, LICENSE, NOTICE and client package metadata are included.
430
- Release automation also publishes the pinned server image to `ghcr.io/knowttl/artium-axi:<release-tag>` with OCI labels and provenance.
431
- See [release publishing](docs/runbook.md#npm-client-releases) for owner setup and image digest and attestation verification before deployment.
133
+ Use `node dist/cli/artium-axi.mjs` in place of `artium-axi` for the same login and discovery steps.
134
+ The root install also installs frozen upstream dependencies; native build approval is limited to argon2, better-sqlite3 and esbuild.
135
+ `pnpm build:npm` stages the public client in `dist/npm`; `npm pack --dry-run ./dist/npm` inspects its contents.
432
136
 
433
- ## Usage
137
+ ## Use with your agent
434
138
 
435
- ### Command surface and subcommands
436
-
437
- | Command | Purpose |
438
- | --- | --- |
439
- | `artium-axi` | Show identity, roles and available tools. |
440
- | `artium-axi --version` | Print only the client package version and a newline, then exit without configuration, sign-in or network access. |
441
- | `artium-axi login --username synthetic-user` | Sign in with a local account. |
442
- | `artium-axi login --sso` | Sign in through browser approval with an enabled SSO provider; works on headless and SSH hosts. |
443
- | `artium-axi passwd` | Change your password, then sign in again. |
444
- | `artium-axi whoami` | Show identity, roles, access expiry and server URL. |
445
- | `artium-axi tools` | List enabled runtime tools granted through your roles. |
446
- | `artium-axi tools show falcon-axi` | Show cached status, vetted pinned help and a first-call example. |
447
- | `artium-axi doctor` | Check server address, certificate, token, CLI version and cached tool health, with a five-second deadline per request. Stop dependent probes after address or TLS connection failure. |
448
- | `artium-axi logout` | Remove local tokens and attempt server-session revocation. |
449
- | `artium-axi setup --host claude --hook` | Install your granted skills and optional Claude Code hook after sign-in. |
450
- | `artium-axi falcon-axi detection list` | Run a Falcon read through the managed adapter. |
451
- | `artium-axi vectra-axi detection list` | Run a Vectra read through the managed adapter. |
452
- | `artium-axi mg-axi entra user list --limit 1` | Run a bounded Graph read through the managed adapter. |
453
- | `artium-axi ldap-axi user list --limit 1` | Run a bounded directory read through the managed adapter. |
454
-
455
- Add `--help` to a local command to inspect its accepted flags.
456
- Top-level help lists command purposes.
457
- Unknown or unexpected local commands, arguments and flags are rejected before configuration, private-channel reads or network access, with valid choices for the relevant command.
458
- Rejected tokens are named, except for `login` and `passwd` input, which is identified by position without printing its value because it may contain a password.
459
- Tool help has two boundaries:
139
+ After signing in, install the base skill and your granted tools' adapted skills:
460
140
 
461
141
  ```sh
462
- artium-axi --help falcon-axi
463
- artium-axi falcon-axi --help
142
+ artium-axi setup --host claude --hook
464
143
  ```
465
144
 
466
- The first prints local Artium help without signing in or contacting the server.
467
- The second forwards `--help` through the authenticated upstream adapter.
468
- A bare `artium-axi falcon-axi` reads recent detections; use `artium-axi falcon-axi --help` for its command list.
469
- A bare Vectra invocation shows upstream help; `artium-axi az-axi` and `artium-axi az-axi home` run the Azure dashboard with ARM authentication.
470
- A bare `artium-axi ldap-axi` shows directory discovery with managed-credential guidance.
471
- Arguments after a tool name belong to upstream, subject to adapter restrictions on credential, configuration and file paths.
472
- Unknown Azure flags return `INVALID_INPUT` with the flag name, valid flags and a hosted help command.
473
- The bundled CLI forwards argument tokens and local Azure files supplied through the reviewed `--file` and `--body-file` flags.
474
- It captures bounded non-terminal stdin only for Azure `rg query` (also `graph query`), `logs query` (also `monitor log-analytics query`) and `api` calls.
475
- Other Azure commands, including the dashboard and `home`, leave stdin unread; help and version calls also leave it unread.
476
- Local upload paths become leaf names in the request; duplicate leaf names and oversized input are refused.
477
- The API supports bounded stdin and named uploads through the [shared API contract](src/shared/api.ts).
478
-
479
- See [write-access administration](docs/runbook.md#roles-credentials-and-health) for per-tool switches, native write gates and the current Falcon limitation.
480
- Artium does not add a universal confirmation flag.
481
-
482
- Azure writes whose outcome is unknown are not retried and return `UNKNOWN_OUTCOME` with state-check guidance; reads may still retry.
483
- Artium also returns this error when its runner times out, cancels or receives a process signal after starting an executed Azure write; read timeouts remain `TIMEOUT`.
484
- Before submitting the write again, follow the returned read commands and inspect the changed state.
485
- Keep `--full` on recovery API GET commands so long changed values are not truncated, including both `Check current state before trying again` and `Verify with` suggestions.
486
- Runner-generated recovery for Sentinel incident updates and comment creation first resolves the incident ID with the suggested `incident show` command, then uses that ID in the suggested API GET to inspect all incident fields or the comments collection.
487
-
488
- ### TOON output behavior
489
-
490
- Discovery and Artium errors use TOON.
491
- Tool listings include their count in the array header; an empty list returns `tools: 0 available` with a reason and next step.
492
- Details read bundled manifests and stored health without fetching credentials or executing upstream help.
493
- Discovery and administration show the server's bundled tool versions, as defined by the [API contract](src/shared/api.ts).
494
-
495
- Upstream calls preserve stdout, stderr and nonzero exit codes.
496
- For Falcon, Vectra, Azure, Graph, LDAP, Azure DevOps and AWX, recognized TOON or JSON root `help` suggestions, plain upstream help and bundled tool-detail help use `artium-axi <tool>` commands, including examples originally invoking `npx -y @knowttl/<tool>`.
497
- Recognized flag listings and command suggestions omit managed flags declared in each pinned [tool inventory](tools/inventories/)'s `unsafeOverrides`, including Graph profile, config and scopes selectors.
498
- LDAP home output lists hosted commands, and recognized connection and TLS recovery hints direct callers to an administrator to update the [stored LDAP credentials](#ldap).
499
- Unrelated content, literal argument values, unknown formats and truncated streams remain unchanged.
500
- Capture is capped at 4 MiB per stream, with truncation diagnostics on stderr.
501
- Artium failures withhold captured output and return exit 2 for usage or client configuration failures, or exit 1 for other failures.
502
- See the [generated error reference](docs/errors.md) for codes, HTTP status, CLI exit status and recovery steps.
503
-
504
- Doctor reads cached tool health rather than running a fresh platform test.
505
- Its certificate diagnostic reports whether the liveness request verified TLS, independently of the HTTP status or response body.
506
- If the connection or CA-file read fails before verification, the certificate remains unverified.
507
- Only `ok` passes; `unknown`, `unconfigured` and `error` require investigation.
508
- If the client reports `CLI_OUTDATED`, download the current bundle and checksum from the server again.
509
-
510
- ### Browser administration
511
-
512
- Open `/login` through the trusted HTTPS proxy.
513
- Temporary passwords open `/password` and require a new login after changing them.
514
- Administrators land on `/admin`; ordinary users land on `/account` for tool access, CLI setup and session management.
515
-
516
- | Screen | Purpose |
517
- | --- | --- |
518
- | `/admin` | Search and filter the users table by source, status or role; create local users. |
519
- | `/admin/users/:id` | Edit profile and roles, review effective tools and sessions, revoke sessions, enable or disable, unlock, reset local passwords and archive. |
520
- | `/admin/invitations` | Prepare, resend and revoke SSO invitations; see [Sign-in settings](#sign-in-settings) for usage and claim availability. |
521
- | `/account` | Review your roles and tools, download and set up the CLI, change your local-account password and revoke your sessions. |
522
- | `/admin/tools` | Review installed tools, pinned versions and cached health. |
523
- | `/admin/tools/:tool` | Configure credentials, native settings and enablement; test health and review granting roles. |
524
- | `/admin/credentials` | Redirect to the merged tools index. |
525
- | `/admin/roles` | List roles and create a role. |
526
- | `/admin/roles/:id` | Rename a role, replace tool grants, review members and delete eligible roles. |
527
- | `/admin/audit` | Filter and page through authentication, administration and tool-call records. |
528
- | `/admin/settings/sign-in` | Configure providers and role rules; see [Sign-in settings](#sign-in-settings). |
529
-
530
- Administrator capability is separate from tool grants.
531
- Role changes apply on the next call, including calls using existing tokens.
532
- User detail combines grants from every assigned role and links each tool to its granting roles.
533
- User detail and role membership pages distinguish Direct assignments made by an administrator from Rule grants.
534
- Saving a user's roles replaces direct assignments and preserves grants originating from SSO rules.
535
- The identity schema supports SSO users, providers, rules and invitations; see [Sign-in settings](#sign-in-settings) for the available provider editor and current SSO limits.
536
- SSO accounts cannot be given a local password.
537
- Disabled and archived users remain listed as role members and must have that role removed before it can be deleted.
538
- Archived user detail allows retained direct assignments to be removed without restoring sign-in; the UI and API refuse new direct assignments, including reassigning a removed direct grant.
539
- See [Sign-in settings](#sign-in-settings) for removing rule-origin grants.
540
- Deleting a role requires no members and no references from SSO rules; remove or retarget its mappings in **Sign-in settings** first.
541
- Any invitation referencing the role prevents deletion, including expired, revoked or claimed invitations, preserving invitation history.
542
- Deletion removes its tool grants and records an audit event.
543
- User search matches literal text anywhere in a username or display name, ignoring case.
544
- The users and role members tables show matching totals; Next page retains the current filters.
545
- See the [shared API contracts](src/shared/api.ts) for user filters, detail responses, role membership pagination and role deletion inputs.
546
- The last enabled administrator cannot be disabled, demoted or archived.
547
- Profile, role and archive changes use revision checks; reload stale forms rather than overwriting newer changes.
548
- Session revocation and administration changes commit with their audit records.
549
- After 15 minutes without identity confirmation, administration mutations require reauthentication.
550
- After a tool credential test fails TLS verification, an administrator can inspect its saved endpoint’s certificate and trust it for that credential in one confirmation.
551
- The UI shows full fingerprints, warnings, expiry and removable trust; hostname and validity verification remain enabled.
552
- A missing intermediate is fetched automatically only when its chain reaches an already-trusted root.
553
- See [credential certificate trust](docs/runbook.md#trusting-one-tool-from-the-administration-ui) for inspection, rotation and the network-path warning.
554
- Administration and account screens share a navigation menu.
555
- Signed-in screens have a header showing identity, sign-in source and sign-out.
556
- On administration screens, the header also shows the remaining confirmation window.
557
- Local admin forms open a password dialog when confirmation expires, then resume the pending action after successful confirmation.
558
- SSO admin forms instead open a confirmation window with the session's provider, with a forced login and fresh authentication-time check.
559
- For Entra, configure `auth_time` as an optional ID-token claim in the application registration, following [Microsoft's optional-claims instructions](https://learn.microsoft.com/en-us/entra/identity-platform/optional-claims).
560
- Confirmation is refused if that claim is absent or stale.
561
- After confirming with the same identity, use **Continue to artium** to resume the pending action in the original window.
562
- Keep the original window open; drafts, including credential fields, remain there and are not stored for the round trip.
563
- Allow popups for artium if the browser blocks the confirmation window.
564
- Cancel keeps the entered values without submitting the change.
565
- SSO sign-out optionally also visits the provider's discovered end-session endpoint, when supported.
566
- After signing out of artium, choose **Continue to provider sign-out** to finish that optional step.
567
- The artium session is revoked first; if provider sign-out cannot be started, the page explains that the provider session may still be active.
568
- Register the artium `/login` URL as an allowed post-logout return URI in the provider before using that option.
569
- Confirmation dialogs explain consequences before changes; each screen also has expandable help.
570
- Timestamps display in the browser's local time, with their UTC value available on hover.
571
-
572
- User detail and Account list active browser sessions and CLI token families.
573
- Revoke ends one whole family, including its access and refresh tokens; Sign out everywhere ends all sessions while allowing a new sign-in.
574
- Revoking your current browser session signs you out immediately.
575
- Account session management requires a normal browser sign-in and CSRF protection, without administrator capability or the [recent confirmation required for administration](#browser-administration).
576
- Users with temporary passwords must change them first.
577
- Archiving disables sign-in, revokes all sessions and hides the user from the users table while retaining identity, role membership and audit history.
578
- Archived users cannot be enabled through the UI or API; use Disable for temporary loss of access.
579
-
580
- Credential editors pre-fill non-secret values and never return stored secrets.
581
- Vectra and Graph use schema-generated fields and validation from their published [AXI credential standard](docs/credential-standard.md) profile schemas.
582
- Enter secret values themselves, not SecretRefs; leave unused fields blank and enter object fields as advanced JSON and string lists one value per line.
583
- Profile-backed credential saves normalize safe differences only when the schema rejects the original value; already valid values, including secrets, remain byte for byte unchanged.
584
- Rejected strings can have surrounding whitespace removed, including nested object and list values; secret interior whitespace is preserved.
585
- For Vectra, `origin` accepts surrounding whitespace, a trailing slash, uppercase scheme or host and an explicit default port, saving a canonical HTTPS origin.
586
- Paths, queries, fragments, embedded credentials and HTTP origins remain invalid.
587
- Rejected profile input returns `INVALID_INPUT` with field names and failing schema constraints, including string lengths, array bounds, uniqueness and unsupported fields, without echoing submitted values.
588
- When the authentication branch is identifiable, guidance reports its failures and conflicting field names without instructions from other branches; independent errors are reported together.
589
- Ambiguous alternatives receive field-combination guidance.
590
- See [Vectra credential setup](#vectra) for private CA input and shared trust.
591
- The form exposes the schema's full requirements, including conditional requirements for the chosen authentication kind.
592
- Azure uses guided source-identity fields because the host brokers resource tokens separately.
593
- Azure and Graph certificate editors accept one PEM file containing one certificate and its matching unencrypted private key and calculate the fingerprint automatically.
594
- See the [hosted contract](docs/credential-standard.md#9-hosted-contract-artium-axi) for profile injection.
595
- Falcon has guided fields; see its [current credential handling](docs/credential-standard.md#per-tool-host-facing-schemas).
596
- Browser saves keep native settings and retain blank stored secrets for the same identity.
597
- Identity changes require new secrets as defined by the [credential-save contract](src/shared/api.ts) (`adminToolRoutes.save`).
598
- Select **Test after saving** to save and report a harmless credential check inline.
599
- After saving, the page reports applied normalizations and reloads stored non-secret values; secret notices name only the field and change, never the value.
600
- See the [credential-save contract](src/shared/api.ts) (`adminToolRoutes.save`) for API inputs and complete replacement semantics.
601
- See [credential rotation](docs/runbook.md#roles-credentials-and-health).
602
- Native settings also replace the entire object; `{}` clears it.
603
- Credential changes clear cached health, and background checks run every 15 minutes for enabled configured tools.
604
- Use **Test credential** for a current fixed read before enabling a configured tool.
605
- For failed tests, follow the [credential diagnostic guidance](docs/runbook.md#scripted-administrator-sessions) and the [error reference](docs/errors.md).
606
- Graph tests read at most one user through `entra user list --limit 1`.
607
- For a new installation, follow [Graph credential setup](#microsoft-graph) and obtain the required permission results and maintainer approval before enabling Graph on a running installation.
608
-
609
- ### Sign-in settings
610
-
611
- Open **Sign-in settings** at `/admin/settings/sign-in` to add a single-tenant Entra ID provider using its name and directory tenant UUID.
612
- Open the provider to save its application client UUID and credential.
613
- Certificate authentication is preferred: paste or upload one PEM containing the certificate and matching unencrypted private key; Artium calculates the SHA-256 fingerprint.
614
- The application's public certificate registration is an owner setup step; saving here does not contact the provider.
615
- A client secret is also accepted, with an in-page warning recommending certificates.
616
-
617
- For another OpenID Connect provider, choose **Add OpenID Connect provider** and enter its name and exact HTTPS issuer URL.
618
- Discovery reads the issuer's OpenID configuration over verified TLS and rejects redirects and mismatched issuers.
619
- Register the provider page's exact callback URI in a confidential web application, then save its client ID and RSA certificate (`private_key_jwt`) or client secret (`client_secret_post` or `client_secret_basic`, selected from discovery with POST preferred).
620
- If discovery omits the supported client-authentication methods, secret authentication defaults to Basic.
621
- The provider must support authorization code with PKCE S256, RS256 ID tokens and scopes `openid profile`.
622
- Configure `preferred_username` for invitation claims and `auth_time` for fresh browser confirmation and CLI approval; generic confirmation requests use `prompt=login` and `max_age=0`.
623
- Generic identities bind to exact issuer and `sub`; Entra continues to bind to `tid` + `oid`.
624
- Multiple enabled providers appear on both the sign-in page and CLI approval page, each with its own callback and state binding.
625
- Assign generic-provider users direct artium roles or configure claim rules for tool access.
626
- Generic rules accept any exact top-level claim name, such as `groups` or `custom.claim`, and match a string or a string in an array against the case-sensitive rule value.
627
- Dots are literal claim-name characters, not nested paths; numbers, booleans and objects do not match.
628
- See [generic OIDC verification](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/verification-p5a.md) for the approved scope split, fake-provider evidence and pending maintainer live acceptance.
629
-
630
- Provider credentials use the encrypted store; their secrets are never returned in pages, API metadata or audit records.
631
- Non-secret fields are pre-filled; leave secrets blank to keep them for the same tenant, client and authentication method.
632
- Changing client or authentication requires a new secret; changing the provider tenant or issuer removes the old credential.
633
- Settings and credential saves require administrator capability and the [confirmation described under browser administration](#browser-administration), check revisions, and are audited.
634
- The [provider and role-rule API contracts](src/shared/api.ts) own the request and response fields.
635
-
636
- Providers start disabled.
637
- The provider page includes its setup guide, copy buttons for redirect and post-logout URIs, and an audited activation control requiring recent authentication.
638
- Activation requires a locally valid matching credential and an enabled, unlocked, unarchived break-glass local administrator with a permanent password.
639
- Test that emergency account in a separate browser before enabling SSO, then test an invitation claim and provider sign-in while keeping break-glass access open.
640
- Local checks cannot prove provider credential acceptance or access-policy configuration.
641
- Saving provider settings or credentials disables that provider; review and enable it again afterwards.
642
- Disabling all providers restores ordinary local password sign-in; existing artium sessions remain active.
643
- Local sign-in continues to work while all providers are disabled.
644
- On a local administrator's user detail page, use **Designate break-glass administrator** to prepare emergency password access.
645
- Designation requires recent identity confirmation, checks the user revision and is audited.
646
- The users table and signed-in header identify designated accounts.
647
- Removing designation revokes that account's browser and CLI sessions; demotion also clears designation, and claiming an SSO link removes it.
648
- When any SSO provider is enabled, only designated local administrators may use password sign-in, password confirmation or password changes, through either browser or bearer routes.
649
- Fresh installations designate no accounts automatically and keep providers disabled.
650
- See [break-glass verification](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/verification-p3c2.md) for local-password policy evidence and [P3 activation verification](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/verification-p3c2b.md) for activation and complete fake-provider browser acceptance.
651
- On an Entra provider page, add, edit or remove role rules mapping an exact, case-sensitive Entra `roles` claim value to an artium role.
652
- Generic provider pages offer the same rule editor with a claim-name field.
653
- Each rule's Who matches link opens the enabled, unarchived users whose last successful sign-in claims match that provider, issuer, claim name and value.
654
- Counts refresh on page reload and include matches for new rules before the next role sync.
655
- These saved claims are not a live directory query; users without recorded sign-in claims are unknown.
656
- See the [upgrade runbook](docs/runbook.md#backup-restore-and-upgrade-rollback) for existing-identity compatibility and [claim-rule verification](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/verification-p5b.md) for local evidence and pending maintainer live acceptance.
657
- The target role supplies tool access; rules never grant administrator capability.
658
- Create roles and grant their tools on **Roles** first.
659
- Every rule change requires the [confirmation described under browser administration](#browser-administration) and is audited atomically; stale edits require reloading the page.
660
- At each SSO sign-in, matching rules add role grants and unmatched rules remove their grants for that provider; direct grants and other-provider grants stay unchanged.
661
- User details label Direct and Rule grants and identify the provider rule that supplied each rule grant.
662
- Deleting a rule or changing its provider, claim name, claim value or target role immediately removes that rule's grants, including those retained by archived users; direct grants and grants from other rules remain unchanged.
663
- Open **Invite SSO user and manage invitations** from Users to prepare an invitation with a provider, display name, exact expected `preferred_username` (Entra sign-in username for Microsoft), direct roles and an expiry of 1 to 30 days (default 7).
664
- To prepare a link for an existing enabled local account, open that user's detail page and choose **Link to SSO**.
665
- Preparing a link preserves the account, password, sessions and grants; nothing changes until claim.
666
- Creation and **Resend invitation** display a bearer link once; copy it before closing the dialog and send it securely yourself.
667
- Artium does not send email and stores only the link token's hash.
668
- Resend replaces the old link and starts a new expiry period, including for expired invitations.
669
- **Revoke invitation** prevents claiming; claimed or revoked invitations cannot be resent.
670
- Every mutation requires administrator capability and the [confirmation described under browser administration](#browser-administration), checks revisions where applicable, and commits with an `invite-create`, `invite-resend` or `invite-revoke` audit event identifying the invitation.
671
- Lists never return link tokens or hashes; expiry is evaluated when read.
672
- The [invitation API contracts](src/shared/api.ts) own the request and response fields.
673
- When a provider is enabled, its invitation link starts browser sign-in and requires an exact, case-sensitive match of the expected username.
674
- Claiming atomically binds the immutable provider identity, consumes the invitation, adds its direct roles and synchronizes that provider's rule roles.
675
- Linking preserves the existing user id, username, display name, administrator flag and history, removes the local password and revokes prior browser and CLI sessions.
676
- An existing identity or username is never automatically linked; expired, revoked, replaced or claimed links cannot grant access.
677
- Claim, link, role-sync and sign-in audit events commit with the account and session changes.
678
- See [browser SSO protocol verification](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/verification-p3b.md) and [SSO reauthentication verification](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/verification-p3c.md) and [P3 activation verification](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/verification-p3c2b.md) for fake-provider evidence and pending maintainer live acceptance.
679
- For CLI SSO, set `ARTIUM_AXI_URL` to this server and run `artium-axi login --sso`.
680
- Open the displayed `/device` URL in any browser, enter the terminal code, choose an enabled provider and complete a fresh sign-in, then review the requesting IP and UTC time before choosing **Approve**.
681
- Approve only a request you started on a device you control, with a code that matches your terminal; never approve a code someone sends you.
682
- Choose **This wasn't me** to deny an unexpected request.
683
- Codes expire after 10 minutes and can grant access only once.
684
- The CLI waits for approval, retries transient polling limits at the returned interval until code expiry, and stores the usual private artium tokens; run `artium-axi login --sso` again after its 8-hour family ends.
685
- No identity-provider public-client or device-code grant configuration is required; this is artium's own approval flow.
686
- Restarting artium invalidates pending approvals; run `login --sso` again.
687
- For bearer SSO reauthentication, send `POST /v1/auth/reauth` with your access token and JSON `{}`.
688
- Approve the returned code through `/device` after a fresh provider sign-in as the same user.
689
- Poll `/v1/auth/reauth` with the same access token and JSON `{ "deviceCode": "<deviceCode>" }`, waiting the returned `intervalMs` milliseconds between polls, until it returns a recent-auth `ticket` and `expiresAt` instead of `status: pending`.
690
- Send the ticket in `x-artium-reauth-ticket` on administration requests; it authorizes only the initiating CLI family and cannot extend its lifetime.
691
- Denial, expiry or revocation prevents ticket issuance; approval codes are single use.
692
- See [CLI device sign-in verification](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/verification-p4a.md) for recorded fake-provider evidence and bearer reauthentication coverage.
693
-
694
- ### Audit screen and API
695
-
696
- Audit supports user, tool, exact event, exact outcome and inclusive UTC From/To filters.
697
- Records contain actor, UTC time, event, outcome, request ID, redacted arguments and safe execution metadata.
698
- Open an event in the table to inspect every persisted field.
699
- Pagination retains filters; starting a new search includes records inserted after the previous search began.
700
-
701
- `GET /v1/admin/audit` exposes the same records with `user`, `tool`, `event`, `outcome`, `from`, `to`, `limit` and `cursor` parameters.
702
- Pages default to 50 records and accept 1 to 100; pass `nextCursor` with the same filters until it is null.
703
- Apply filters, then use **Download CSV** or **Download JSON lines** to export every matching retained record, across all pages.
704
- `GET /v1/admin/audit/export?format=csv` (or `format=jsonl`) accepts the same filters, excluding `limit` and `cursor`.
705
- Exports are newest first and exclude records inserted after the download begins.
706
- Both formats contain the same safe persisted fields as `ARTIUM_AXI_AUDIT_STDOUT`, never credentials, tokens or tool output.
707
- CSV quotes non-null values and leaves null fields empty; JSON lines preserves JSON types and nulls.
708
- An empty result produces a CSV header or an empty JSON-lines file.
709
- Browser reads require administrator capability; bearer reads also require a session-bound recent-reauthentication ticket.
710
- There is no audit mutation or deletion route.
711
- Successful local password confirmations and SSO browser and bearer confirmations emit `reauth` events.
712
- Successful local sign-in, password confirmation and password-change records include `authentication_method` as `local` or `break-glass`.
713
- These events are flagged as `break-glass` for designated accounts, even before SSO activation; Audit highlights them and includes the same field in its exports and JSON stdout stream.
714
- SSO reauthentication events include the authentication method, provider and validated subject.
715
- Device approval and refusal emit `device-approve` and `device-deny` events, with the requesting IP in `arguments.requestingAddress` and the approving or denying browser's IP in `client_address`.
716
- Each `run-terminal` record uses `action` to report `write` when the native tool journal contains valid JSON object records for that run, or `read` when a successful run leaves its supported journal absent or empty.
717
- This records journal activity, including mutation intents, rather than guaranteeing that a remote change succeeded.
718
- Pinned Falcon and LDAP runs report `read` from their inventories' read-only declarations, including normal runs and health checks.
719
- ADO and AWX use host classification: reads report `read`, successful write calls report `write`, and failed or interrupted writes report `unknown`.
720
- For tools with native journals, failures without journal records and malformed or unreadable evidence report `unknown`; recovered interrupted runs also report `unknown`.
721
- See the [API contract](src/shared/api.ts) and [retention and export runbook](docs/runbook.md#retention-and-export).
145
+ Use `--host codex`, `--host opencode` or `--host pi` without `--hook` for those hosts.
146
+ Only Claude Code supports the optional `SessionStart` hook, which injects the `tools` discovery output.
147
+ Setup preserves unrelated settings and refuses edited/unmanaged skills unless `--force` is explicit.
148
+ Re-run setup after moving the executable or changing grants; skills for removed grants are retained and reported.
149
+ See [installation paths and manual removal](docs/client-reference.md#agent-installation) before uninstalling.
150
+ Artium's authenticated setup fetches managed skills; a standalone skill installer does not configure this server account.
722
151
 
723
- ## Configuration
152
+ ## Safety
724
153
 
725
- ### Client settings
154
+ All tools start disabled; write access defaults to off.
155
+ Administrator capability alone grants no tool access; upstream permissions remain an additional boundary.
726
156
 
727
- | Variable | Meaning |
157
+ | Tool | Write capability and unlock |
728
158
  | --- | --- |
729
- | `ARTIUM_AXI_URL` | Required HTTPS base URL without credentials, query or fragment. |
730
- | `ARTIUM_AXI_CA_FILE` | Optional readable PEM CA file added to Node's certificate trust. |
731
- | `ARTIUM_AXI_PASSWORD` | Ordinary login password source when `--password-stdin` is absent, before the terminal prompt; refused for [managed sign-in](#externally-managed-client-sessions). |
732
- | `ARTIUM_AXI_CURRENT_PASSWORD` | Current password for an ordinary password change, before the terminal prompt. |
733
- | `XDG_CONFIG_HOME` | Session-file base on Linux/macOS; otherwise `~/.config`. |
734
- | `APPDATA` | Session-file base on Windows, whose execution remains unverified. |
735
- | `ARTIUM_AXI_TEST_HTTP` | `1` permits loopback HTTP for tests only. |
736
-
737
- Use `login --password-stdin` or `passwd --password-stdin` to supply the login or new password through stdin.
738
- Stdin removes one final LF or CRLF and preserves all other spaces and Unicode.
739
- Password arguments are refused; tokens are never printed to stdout or stderr.
740
- Ordinary password changes also require the current password through the terminal prompt or `ARTIUM_AXI_CURRENT_PASSWORD`.
741
- Clear password environment values after use.
742
-
743
- By default, sessions live in `artium-axi/session.json` under the applicable base directory and are bound to the normalized server URL.
744
- Callers that manage their own tokens can instead use [externally managed client sessions](#externally-managed-client-sessions).
745
- POSIX directories use mode 0700 and files mode 0600; Windows uses a restricted ACL and refuses storage if it cannot establish it.
746
- Do not export or share the session file.
747
- CLI processes serialize refreshes through `session.lock`; after `SESSION_BUSY`, remove that lock directory only when every CLI process has exited.
748
- Concurrent login or logout can produce `SESSION_CHANGED`; check the current session before repeating a command.
749
- Logout removes local tokens even if remote revocation fails, reporting `remoteRevocation: unverified` in that case.
750
-
751
- Certificate verification remains enforced even with `NODE_TLS_REJECT_UNAUTHORIZED=0`, and authenticated redirects are refused.
752
- Only an explicit pre-execution `TOKEN_EXPIRED` response permits one serialized refresh and retry.
753
- A network failure or uncertain command outcome is never retried automatically.
754
-
755
- ### Externally managed client sessions
756
-
757
- Callers that keep credentials outside the CLI can opt in with one leading flag: `artium-axi --managed-session <command> <args>`.
758
- The caller supplies inherited pipes or sockets: fd 3 for session input on authenticated calls and fd 4 for private new-session and rotation output.
759
- Stdin remains available for tool input; stdout and stderr retain their normal command formats.
760
- Do not pass tokens in arguments or environment variables, connect fd 4 to a log or public output, or redirect either private channel to a disk file.
761
- The CLI refuses regular files as private channels and never reads, creates, locks, updates or deletes `session.json` in this mode.
762
-
763
- For authenticated calls, send one UTF-8 JSON object of at most 64 KiB to fd 3, then close the input pipe:
764
-
765
- ```json
766
- {"serverUrl":"https://artium.example.test","accessToken":"CANARY-access","refreshToken":"CANARY-refresh"}
767
- ```
768
-
769
- `serverUrl` must match the normalized `ARTIUM_AXI_URL`, allowing a final slash.
770
- `accessToken` is required and nonempty; `refreshToken` is optional and nonempty when supplied.
771
- The optional fields `status: "authenticated"`, `accessExpiresAt` and `familyExpiresAt` (integer Unix milliseconds) allow a rotation record to be reused as input; other fields are refused.
772
- The caller owns expiry policy, refresh serialization across processes and secure persistence.
773
- Managed mode supports `login`, the home view, `whoami`, `tools`, `tools show`, `doctor` and tool commands.
774
- `passwd`, `logout` and `setup` are refused before any network call; ordinary sign-in and its server-version warning remain unchanged without the flag.
775
- Help is available without private channels through `artium-axi --help`; use `artium-axi --managed-session --help` or `artium-axi login --help` for the pipe protocol.
776
-
777
- To obtain the first session, run `artium-axi --managed-session login --username <username> --password-stdin` with the password on protected inherited stdin, or `artium-axi --managed-session login --sso` for browser approval.
778
- Login does not read or require fd 3; it requires a writable private pipe or socket on fd 4 before contacting the server.
779
- Password arguments and `ARTIUM_AXI_PASSWORD` are refused, including when `--password-stdin` is present; unset that variable before managed sign-in.
780
- Password input follows the stdin rules in [client settings](#client-settings).
781
- SSO displays the approval URL and user code immediately so the user can approve while the CLI waits.
782
- Both sign-in methods return the new session as one newline-terminated JSON object on fd 4, using the same envelope shown below for rotations, and create nothing under the config or session paths.
783
- The login server-version warning still appears on stderr when versions differ.
784
- If a local account requires a password change, fd 4 instead receives `{serverUrl, status: "password-change-required", passwordChangeToken, passwordChangeExpiresAt}` and the command returns `PASSWORD_CHANGE_REQUIRED` (exit 1).
785
- That restricted record is not valid managed-session input; the caller must complete the password change through the server API and sign in again.
786
-
787
- Only an explicit `TOKEN_EXPIRED` response permits a single refresh and retry of that request.
788
- Without a refresh token, or if refresh is refused, the CLI returns the authentication error for the caller to handle.
789
- Network failures and uncertain outcomes are never automatically retried.
790
- After a successful refresh, fd 4 receives one newline-terminated JSON object before the request is retried:
791
-
792
- ```json
793
- {"serverUrl":"https://artium.example.test","status":"authenticated","accessToken":"CANARY-new-access","refreshToken":"CANARY-new-refresh","accessExpiresAt":1800000000000,"familyExpiresAt":1800003600000}
794
- ```
159
+ | Falcon, LDAP | Read-only inventories; Falcon's NG-SIEM search-job start/stop effects remain available regardless of its ineffective write switch. LDAP has no writes. |
160
+ | Azure | Reviewed resource mutations; administrator `allowWrites: true` plus native command gates. |
161
+ | Graph, Vectra | Native mutations only with administrator `writes.allowWrites: true` and an explicit operations allow-list, plus native gates. |
162
+ | Azure DevOps | Reviewed mutations with administrator `allowWrites: true`; raw `api` remains GET-only. |
163
+ | AWX | Launch/cancel/relaunch, workflow approval/denial, project/inventory-source sync and notification tests with `allowWrites: true` and upstream `--confirm`; configuration, deletion and security writes stay blocked. |
795
164
 
796
- Every rotation is delivered even if the subsequent request fails; an authenticated invocation without rotation writes no record.
797
- Consume fd 4 concurrently with stdout and stderr, and retain new sessions and rotations regardless of the command's exit status.
798
- If new-session or rotation delivery fails, the CLI returns `INVALID_INPUT` (exit 2); the caller must recover the session.
799
- After failed rotation delivery, the CLI refuses to retry the request; do not reuse the consumed refresh token.
800
- Managed public output is buffered and scanned against supplied, newly issued and rotated tokens and their canonical encodings before printing; a match withholds both buffered streams and returns `SECRET_IN_OUTPUT`.
801
- SSO approval instructions are displayed before session issuance; managed password input and the private SSO device code are also checked against buffered output.
165
+ There is no universal Artium confirmation flag.
166
+ Use authenticated tool help and the [write-access runbook](docs/runbook.md#roles-credentials-and-health) for operation-specific gates.
167
+ After an unknown write outcome, inspect state using returned guidance before retrying.
802
168
 
803
- Exit codes are 0 for success, 2 for invalid input, client configuration or private channels and refused commands, and 1 for authentication, server-binding, transport or output-scanning failures.
804
- Tool exit codes pass through as usual.
805
- Missing or closed descriptors, invalid JSON and mismatched server bindings fail before network access; no failure falls back to a session file.
169
+ | Initial read | Required upstream permission |
170
+ | --- | --- |
171
+ | Falcon detections | `Alerts:read` |
172
+ | Vectra credential test | Health reads plus permissions for intended data |
173
+ | Azure subscription list | Application access to intended subscriptions; data-plane roles separately |
174
+ | Graph first-user read | Application `User.Read.All` with administrator consent |
175
+ | LDAP | Bind identity with directory read access |
176
+ | Azure DevOps project list | Identity permitted to view the organization/project |
177
+ | AWX job list | Token identity with job read access |
178
+
179
+ See [tool credentials](docs/tool-credentials.md) for dedicated identities, permissions and safe credential entry.
180
+ Artium stores shared service credentials encrypted with AES-256-GCM and never returns saved secrets to clients.
181
+ The data volume also holds the plaintext master key beside SQLite: protect the entire volume and keep offline escrow separate.
182
+ Linux client sessions use a mode-0700 directory and mode-0600 file under `${XDG_CONFIG_HOME:-~/.config}/artium-axi`.
183
+ Access tokens last one hour, with 12-hour local or 8-hour SSO CLI families; password changes revoke sessions.
184
+
185
+ Requests, bounded tool input and uploads travel to the server; enabled tools contact their upstream APIs using shared service identities.
186
+ Audit excludes injected credentials, request bodies, stdin, uploads and output streams.
187
+ The runner scans known secret encodings and discards output on a match; unknown upstream-minted tokens cannot be identified by exact-value scanning.
188
+ Its restricted environment, private directories and process limits are not a complete sandbox; descendants starting a new session can escape process-group termination.
806
189
 
807
- ### Server settings and custody
190
+ ## Configuration
808
191
 
809
- | Variable | Meaning |
192
+ | Setting or flag | Purpose |
810
193
  | --- | --- |
811
- | `ARTIUM_AXI_DATABASE_FILE` | SQLite database path; default `/data/artium.db`. |
812
- | `ARTIUM_AXI_MASTER_KEY_FILE` | Initial or explicit master-key file containing exactly 32 raw bytes; takes precedence over other key sources. |
813
- | `ARTIUM_AXI_MASTER_KEY` | Alternative canonical base64 encoding of exactly 32 key bytes. |
814
- | `ARTIUM_AXI_EXTRA_CA_FILE` | Optional readable PEM bundle of public CA certificates for upstream TLS, including TLS inspection; mounted read-only. Loaded at startup; see the [private CA runbook](docs/runbook.md#tls-inspection-and-private-upstream-cas). |
815
- | `ARTIUM_AXI_ADMIN_USERNAME` | First-start local administrator username. |
816
- | `ARTIUM_AXI_ADMIN_PASSWORD_FILE` | UTF-8 file containing the exact first-start password, without an added newline. |
817
- | `ARTIUM_AXI_TRUSTED_PROXIES` | Comma-separated verified proxy source IP addresses; default trusts none. |
818
- | `ARTIUM_AXI_AUDIT_STDOUT` | `1` streams committed audit records as JSON lines; SQLite remains authoritative. |
819
-
820
- The server listens on HTTP port 8080 behind a trusted HTTPS reverse proxy.
821
- The [Compose example](compose.example.yaml) publishes only on host loopback and supplies a master-key secret, not bootstrap credentials.
822
- Follow the [first-administrator runbook](docs/runbook.md#first-administrator-and-offline-recovery) before starting a new store.
823
- All tools start disabled until configured.
824
- The proxy must replace incoming forwarding headers, and clients must not reach the HTTP listener directly.
825
- Public `/health/live` checks liveness; `/health/ready` checks local migration-table access, not upstream services.
826
-
827
- Startup validates the store's key binding and every encrypted credential before listening.
828
- It saves the plaintext master key as canonical base64 in an owner-only `.env` beside the database, even when the key came from a mounted file.
829
- **The data volume therefore contains both the encrypted database and its decryption key.**
830
- Protect the whole volume and keep key escrow separate from database backups.
831
- With no explicit key source, later starts and maintenance commands read the saved key; no key is generated or uploaded.
832
- Invalid or mismatched keys fail startup.
833
- See [backup, restore, rotation and rollback](docs/runbook.md#backup-restore-and-upgrade-rollback) for matching-key recovery, backup retention and unresolved owner custody choices.
834
-
835
- ### Security and acceptance boundaries
836
-
837
- Development and verification use only fakes, synthetic identities and canary credentials.
838
- Fake-service results do not establish live platform permissions or production readiness.
839
- Never put tokens or keys in arguments, source files, images or logs.
840
- The server refuses the removed development-authentication settings `ARTIUM_AXI_DEV` and `ARTIUM_AXI_DEV_TOKEN_FILE`.
841
-
842
- Local passwords use Argon2id and accept any non-empty password of at most 512 UTF-8 bytes, preserving spaces and Unicode.
843
- The byte cap bounds input to native hashing; there are no minimum-length, character-count or common-password rules.
844
- Access tokens last one hour within an 8-hour SSO CLI family or a 12-hour local CLI family; refresh-token reuse revokes the family.
845
- Password changes revoke existing CLI tokens and browser sessions.
846
- See [browser administration](#browser-administration) for session management and user archival.
847
- Sign-in limits and persistent account lockout are enforced by the [attempt boundary](src/server/auth/attempts.ts) and [configured defaults](src/server/config.ts).
848
- Successful login and reauthentication do not consume the per-username failed-attempt budget; the per-address budget still counts successful and failed attempts.
849
- Rate-limit refusals produce a `sign-in` audit record with outcome `AUTH_RATE_LIMITED` and no user identity.
850
- Browser sessions use Secure, HttpOnly, SameSite=Strict cookies and expire after 30 minutes idle or 12 hours overall; temporary-password sessions last 10 minutes.
851
- Browser mutations require same-origin requests and CSRF tokens.
852
-
853
- Credentials are encrypted with AES-256-GCM and retrieved only after authorization and audited admission.
854
- Version 1 uses one shared service credential per tool; external secret sources and per-user credentials remain deferred.
855
- Audit excludes injected credentials, request bodies, stdin, uploaded contents and output streams, and redacts Azure query arguments, including positional KQL.
856
- Failure to persist admission prevents execution; failure to persist the terminal event withholds the result.
857
- Startup recovery records interrupted calls without replay.
858
- Native write journals complement Artium audit and isolate concurrent calls so reads do not inherit another call's write tag.
859
- See the [retention and export runbook](docs/runbook.md#retention-and-export) for journal locations, formats and cleanup.
860
-
861
- The runner uses argument arrays without a shell, a restricted child environment, private per-call directories and bounded concurrency, runtime and output.
862
- Known injected secrets are scanned in raw, JSON-escaped, base64, base64url and URL-encoded output, including beyond capture limits; a match discards both streams.
863
- Exact-value scanning cannot identify unknown tokens minted upstream.
864
- Heap and address-space limits are not complete process isolation: descendants starting a new session escape the runner's process group.
865
- See [runner verification and limitations](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/verification-s09-10.md) and [secret-scanner evidence](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/verification-s07.md).
866
-
867
- ## Development & Testing
868
-
869
- See [CONTRIBUTING.md](CONTRIBUTING.md) for local no-mistakes delivery, container acceptance and the alias deprecation policy.
870
-
871
- Use Linux with the [source toolchain](#build-from-source), OpenSSL, Python 3, curl and sha256sum.
872
- Container acceptance additionally requires Docker and the BuildKit prerequisites described in the [container evidence](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/verification-s20-21.md).
873
- `pnpm test:containers` starts a private BuildKit worker with `--privileged`; hosts that forbid privileged containers cannot run this check and must record container acceptance as unverified.
194
+ | `ARTIUM_AXI_URL` | Required trusted HTTPS origin |
195
+ | `ARTIUM_AXI_CA_FILE` | Additional readable PEM trust bundle for the client |
196
+ | `XDG_CONFIG_HOME` | Linux session-storage base, default `~/.config` |
197
+ | `--password-stdin` | Login/new password via protected stdin |
198
+ | `--host`, `--hook`, `--force` | Setup host, optional Claude hook, explicit skill replacement |
199
+ | `--managed-session` | Caller-owned tokens through private pipes; see client reference |
200
+ | `--help`, `--version` | Local discovery without sign-in |
874
201
 
875
- ```sh
876
- pnpm install --frozen-lockfile
877
- pnpm check
878
- pnpm test:containers
879
- ```
202
+ See the [client reference](docs/client-reference.md) for password inputs, refresh behavior, uploads and managed sessions.
203
+ Server settings, SSO and browser administration live in the [administrator guide](docs/admin-guide.md).
204
+ Recovery, rotation, retention, backups and release gates live in the [operations runbook](docs/runbook.md).
880
205
 
881
- `pnpm check` verifies generated error-reference freshness, strict type checking, parser/schema inventory freshness, the Vitest suite, compilation and the AXI/distribution checklist.
882
- See [checklist verification](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/verification-s46.md) for the fake-only download, authentication, setup and first-call checks.
883
- It refuses unverified host platforms.
206
+ ## Commands
884
207
 
885
- The [Vitest configuration](vitest.config.ts) separates unit and integration projects.
886
- Only the integration project loads the [reduced-cost password hashing setup](test/fixtures/integration-setup.ts); local authentication unit tests and the native smoke retain production hashing costs, as does the dummy hash used for missing accounts.
208
+ This summary follows the [CLI help registry](src/cli/help.ts); `artium-axi --help` prints its complete current command list.
887
209
 
888
- | Command | Scope |
210
+ | Command | Purpose |
889
211
  | --- | --- |
890
- | `pnpm lint` | Static TypeScript checking. |
891
- | `pnpm test` | Inventory/schema freshness checks and the full Vitest suite. |
892
- | `pnpm build` | Server compilation and standalone client bundle. |
893
- | `pnpm test:security` | Tests whose names contain `security`. |
894
- | `pnpm test:containers` | Fake-only runner, walking-skeleton, Graph headless and fake-service container acceptance. |
895
- | `pnpm test:browser` | Real admin pages in an isolated Chrome session through `chrome-devtools-axi`, against the local fake browser harness. |
896
- | `pnpm test:containers --measure-cache` | The container block plus an identical-input warm runner build measurement. |
897
- | `pnpm errors:generate` | Regenerate the error reference after changing the catalogue. |
898
-
899
- The container block builds before running independent acceptance phases concurrently, emits head/input/output evidence and timings, and waits for every phase before removing its uniquely owned test images and private BuildKit cache.
900
- The [gate configuration](.no-mistakes.yaml) owns the paths that require container acceptance and the CLI, documentation, workflow and skill-only exemptions.
901
- Every release requires container acceptance under the [release prerequisites](docs/runbook.md#npm-client-releases).
902
- Do not touch shared Docker resources or use real service credentials.
903
- Changed relevant inputs invalidate earlier container evidence.
904
- Upstream pins and integrity records live in [tools/package.json](tools/package.json), [tools/integrity.json](tools/integrity.json) and [tools/falcon-source.json](tools/falcon-source.json).
905
- The root install runs the frozen upstream install; native build approval is limited to argon2, better-sqlite3 and esbuild, with upstream build scripts disabled.
906
-
907
- ### Private hygiene check
908
-
909
- Before publishing a candidate, commit and build it, then set `ARTIUM_AXI_HYGIENE_DENY_LIST_FILE` to an absolute path to the private deny list **outside the checkout** and run:
212
+ | `artium-axi` | Identity, roles and available tools |
213
+ | `login --username <username>` / `login --sso` | Local password / browser approval |
214
+ | `passwd` / `logout` | Change password / remove local tokens and attempt revocation |
215
+ | `whoami` | Identity, roles, expiry and server |
216
+ | `tools` / `tools show <tool>` | Granted enabled tools / pinned help and first call |
217
+ | `doctor` | Server, TLS, token, version and cached health; five-second request deadlines |
218
+ | `setup --host <host>` | Install managed skills and optional Claude hook |
219
+ | `<tool> <args>` | Run any of the seven managed tools above |
220
+ | `--managed-session --help` | Private-pipe session protocol |
910
221
 
911
- ```sh
912
- pnpm hygiene:check
913
- ```
222
+ `artium-axi --help falcon-axi` is local help; `artium-axi falcon-axi --help` authenticates and calls upstream.
223
+ The [full client reference](docs/client-reference.md#command-surface-and-subcommands) describes forwarding and supported input.
224
+
225
+ ### TOON output and errors
226
+ Discovery and Artium errors use TOON on stdout; progress uses stderr.
227
+ Upstream stdout, stderr and exit status pass through, with managed suggestions adapted to Artium commands.
228
+ Artium exits 0 for success, 2 for usage/configuration errors and 1 for authentication/server/transport failures.
229
+ See the generated [error catalogue](docs/errors.md) for actionable codes and retry guidance.
230
+
231
+ ## Platform limits
232
+
233
+ Linux client and Linux amd64 container paths have local fake-service acceptance.
234
+ Windows/macOS execution, token storage and actual agent-host loading remain unverified.
235
+ Local tests do not establish live vendor permissions or production host acceptance.
236
+ LDAP uses simple bind over verified TLS; ambient Kerberos, per-user upstream credentials and external secret stores are unsupported.
237
+ Azure has reviewed bounded input/upload support; ADO and AWX reject stdin and file uploads.
238
+ See [adapter limits](docs/tool-credentials.md) and [deployment requirements](docs/runbook.md#scope-and-prerequisites).
239
+
240
+ ## Contributing
241
+
242
+ Use Linux and run `pnpm check`; every change uses local no-mistakes validation, with no hosted test CI.
243
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for hygiene checks, conditional container acceptance and the mandatory release container gate.
914
244
 
915
- The UTF-8 list contains one literal term per line, matched after trimming whitespace using context-independent Unicode simple case folding; blanks and case-equivalent duplicates are ignored.
916
- Unset, unreadable, empty or in-tree lists fail.
917
- Never copy real terms or the list into this repository.
918
- Record only its revision or SHA-256, candidate commit and pass/fail result.
245
+ ## License
919
246
 
920
- The check scans tracked, untracked and ignored files, generated output and every commit message reachable from `HEAD`, excluding only `.git` metadata and installed `node_modules` directories.
921
- Supply intended release assets outside the checkout as additional `pnpm hygiene:check` arguments, keeping the list outside those directories too.
922
- Symlinks, unreadable files and BOM-marked UTF-16/UTF-32 assets fail rather than reducing coverage; convert unsupported encodings to UTF-8.
923
- Diagnostics report location (with one-based columns in the original text's UTF-16 code units) and normalized entry number without secret excerpts, and redact labels whose paths match a term using the same folding rule.
924
- The scan cannot guarantee absence of unknown sensitive values and does not approve publication.
247
+ [MIT](LICENSE).
925
248
 
926
- Further operational guidance lives in the [runbook](docs/runbook.md); local implementation and deferred live acceptance are tracked in the [evidence ledger](https://github.com/knowttl/artium-axi/blob/archive/internal-docs/docs/evidence-ledger.md).
249
+ If this project saved you time or helped your workflow, please consider giving it a ⭐ on GitHub to help others find it!
@@ -20140,7 +20140,6 @@ var certificateInspectionSchema = external_exports.strictObject({
20140
20140
  warnings: external_exports.array(external_exports.string()),
20141
20141
  reason: external_exports.string(),
20142
20142
  verificationError: external_exports.string().nullable(),
20143
- repairAvailable: external_exports.boolean(),
20144
20143
  previousFingerprints: external_exports.array(external_exports.string())
20145
20144
  });
20146
20145
  var trustedCredentialCertificateSchema = external_exports.strictObject({
@@ -20148,7 +20147,7 @@ var trustedCredentialCertificateSchema = external_exports.strictObject({
20148
20147
  endpoint: external_exports.string(),
20149
20148
  certificate: certificateDetailsSchema,
20150
20149
  leaf: certificateDetailsSchema,
20151
- mode: external_exports.enum(["pin", "intermediate"]),
20150
+ mode: external_exports.enum(["ca", "pin"]),
20152
20151
  createdAt: external_exports.number().int()
20153
20152
  });
20154
20153
  var adminCertificateRoutes = {
@@ -20167,7 +20166,7 @@ var adminCertificateRoutes = {
20167
20166
  trust: {
20168
20167
  method: "POST",
20169
20168
  path: "/v1/admin/tools/:tool/certificates/trust",
20170
- input: external_exports.strictObject({ inspectionId: external_exports.string() }),
20169
+ input: external_exports.strictObject({ inspectionId: external_exports.string(), mode: external_exports.enum(["ca", "pin"]).default("ca") }),
20171
20170
  response: external_exports.strictObject({ trusted: external_exports.literal(true) })
20172
20171
  },
20173
20172
  remove: {
@@ -20206,6 +20205,22 @@ var adminToolRoutes = {
20206
20205
  authorization: "administrator-and-recent-auth",
20207
20206
  auditEvent: null
20208
20207
  },
20208
+ // Save a canonical HTTPS origin before AWX password sign-in, without sending secrets.
20209
+ // A changed origin removes the token and scoped trust; the same origin retains both.
20210
+ // An origin-only record permits certificate inspection but remains unconfigured for calls and tests.
20211
+ // Both current revisions are required; saving advances both and clears cached health.
20212
+ saveOrigin: {
20213
+ method: "PUT",
20214
+ path: "/v1/admin/tools/awx-axi/origin",
20215
+ input: external_exports.strictObject({
20216
+ origin: external_exports.string(),
20217
+ expectedRevision: external_exports.number().int().nonnegative(),
20218
+ expectedToolRevision: external_exports.number().int().positive()
20219
+ }),
20220
+ response: adminCredentialSchema,
20221
+ authorization: "administrator-and-recent-auth",
20222
+ auditEvent: "save-awx-origin"
20223
+ },
20209
20224
  replace: {
20210
20225
  method: "PUT",
20211
20226
  path: "/v1/admin/tools/:tool/credential",
@@ -20223,6 +20238,9 @@ var adminToolRoutes = {
20223
20238
  // certificate and matching unencrypted private key; the host derives the fingerprint.
20224
20239
  // Omitted optional non-secret fields are removed; explicit empty or null secrets are invalid.
20225
20240
  // Changing mode, kind, auth, tenantId, clientId, origin or org requires new secrets.
20241
+ // AWX PUT/PATCH accept signIn: 'password', username and password instead of token.
20242
+ // Password sign-in requires origin to match the saved origin, exchanges the username and password
20243
+ // for a token before storage and does not retain either. Token input and password input are exclusive.
20226
20244
  // Native settings are retained; edits belong to patch above and are rejected inside value here.
20227
20245
  // Both current revisions are required (credential revision 0 before first save);
20228
20246
  // stale edits fail with REVISION_CONFLICT without mutation.
@@ -20545,7 +20563,7 @@ import { rootCertificates } from "node:tls";
20545
20563
  // package.json
20546
20564
  var package_default = {
20547
20565
  name: "artium-axi",
20548
- version: "0.0.7",
20566
+ version: "0.0.9",
20549
20567
  private: true,
20550
20568
  license: "MIT",
20551
20569
  type: "module",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knowttl/artium-axi",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "Client CLI and embedded skill for the Artium managed tools server.",
5
5
  "license": "MIT",
6
6
  "type": "module",