36 capabilities

Features

Six groups, and none
of them repeats another

nanoinfra runs on your machine and reaches your servers with credentials you hold. This page lists what it does, and each row links to the page that specifies it.

The boundary

Every remote action passes through it. Nothing here is optional or configurable away.

01

Capability gates

The gate answers each action with allow, approve, grant or deny. It reads the action class, the scope and the context. An unattended turn gets the strictest answer, because nobody is watching it.

capability-gates →

4 answers · 3 scopes · 3 contexts

02

Standing grants

A grant names the contexts, the resolved hosts and the exact command strings. A command that differs by one character does not match. A grant never overrules a deny.

capability-gates →

written in config, reviewed like code

03

Privilege split

Four processes run on four accounts, and they answer to four names in ps: gateway, exec, fetch and mcp. The executor holds the credential store and the decision. The agent holds neither.

deployment →

landlock abi 6 · a policy per helper

04

Audit trail

The executor appends every decision to a log that the agent reads and cannot write. A denial latches for the session, and the latches come back from that log after a restart.

capability-gates →

one segment per UTC day

05

Named approvers

The approver set lives in config, not in who can reach the bot. An approval must arrive on a path the request did not choose. A timeout refuses.

capability-gates →

identity independence · approval paths

06

Verified identity

A proxy in front asserts who you are and the gateway verifies that assertion against the provider's keys. It runs no login flow and holds no client secret: it reads one header, checks a signature, and takes the identity from one claim. Who may enter is a list in config, and it is not the list of whose approval counts.

websocket →

jwt verified · allowedIdentities · google, keycloak, dex, cloudflare access

07

A workspace and sessions per person

A verified identity turns the workspaces root into that person's own directory, and their sessions belong to them. Storage is keyed on the issuer and the subject claim, never on the email address, because an address can be renamed or reassigned to somebody else. Asking for another person's workspace is refused; asking for their session answers 404, because a 403 would say it exists.

webui →

keyed on iss + sub · refused, not corrected

Your infrastructure

What the agent reaches, and how it authenticates.

08

Server inventory

Each server names a host, a connection method and a credential. The agent reads the inventory. It never reads the credential.

secrets-and-servers →

ssh · ansible · aws ssm · http

09

Remote execution

The executor runs the command, streams the output and writes a job record. The agent renders that record. Both accounts write the job store, so the mode allows it.

secrets-and-servers →

one job record per action

10

Sealed secrets

Secrets stay encrypted at rest in a local store or in Postgres. No route and no tool returns a plaintext value. The agent process runs without the key.

secrets-and-servers →

the executor decrypts, once, per action

11

Remote job history

Every remote action leaves a job record with its command, its exit code and its output. The WebUI reads those records. A restart reconciles the ones it interrupted.

secrets-and-servers →

streamed while it runs

12

Topology diagrams

The agent draws and edits saved diagrams of your estate. You edit the same files.

diagrams →

drawio · mermaid · png export

gates: unattended mutate.remote host=grant group=deny all=deny
gates: unattended mutate.inventory deny
gates: unattended credential.access grant
gates: standing grants 3, each naming its hosts and its exact commands
confinement: landlock abi 6 on each helper process
confinement: tcp a port allowlist for the fetcher, and no listener anywhere
audit: gate log append only, read by the agent, written by the executor
gates: unattended mutate.remote host=grant group=deny all=deny
gates: unattended mutate.inventory deny
gates: unattended credential.access grant
gates: standing grants 3, each naming its hosts and its exact commands
confinement: landlock abi 6 on each helper process
confinement: tcp a port allowlist for the fetcher, and no listener anywhere
audit: gate log append only, read by the agent, written by the executor

Work that runs without you

Unattended turns, and what tells you what they will meet.

13

Schedules

A cron expression starts a turn. Each run retries with backoff and writes a run record.

automations →

clock · timezone aware

14

Triggers

A file drop or an HTTP call starts a turn. Each trigger carries its own key.

automations →

nanoinfra trigger · POST /api/triggers

15

Commissioning

Creating an automation runs it once with every gated tool forced to preview. Nothing executes. The report names the grant a scheduled run would need. A refused automation saves itself disabled.

automations →

verdict: ok · refused · error

16

Automation state

An automation keeps notes between runs. Only the turn that owns them can read them.

automations →

scoped by the running turn

17

Sustained goals

A long task keeps its own goal state across turns. The agent continues it instead of starting again.

concepts →

turn continuation

18

Memory upkeep

A heartbeat checks a task list. Dream consolidates history in two phases. An idle session compacts itself.

memory →

session ttl · consolidation ratio

The agent

The loop, the models it calls, and the tools it holds.

19

Providers

One agent loop calls Anthropic, OpenAI-compatible endpoints, Azure, Bedrock, GitHub Copilot, OpenAI Codex or xAI. A fallback list takes over when a model fails.

providers →

8 provider families

20

Model presets and fallback

A preset names a model, a context window and a reasoning effort. You switch preset in the chat. A fallback list takes the next model when one fails.

providers →

/model <preset>

21

Tools

The agent reads and edits files, applies patches, runs a shell, searches the web, fetches a page, generates an image and edits notebooks.

concepts →

30 tools · discovered at start

22

Sandboxed shell

A local command runs inside bubblewrap when the host supports it. Web search and web fetch run in a separate confined process.

deployment →

fetcher: tcp 53 · 80 · 443

23

Images and audio

The agent generates images through a provider you configure. It transcribes audio a channel delivers.

image-generation →

generate · transcribe

24

Subagents

The agent starts subagents for work it can hand off. A limit bounds how many run at once. Subagents that share a workspace share one read tracker.

concepts →

1 to 8 concurrent

gates: unattended mutate.remote host=grant group=deny all=deny
gates: unattended mutate.inventory deny
gates: unattended credential.access grant
gates: standing grants 3, each naming its hosts and its exact commands
confinement: landlock abi 6 on each helper process
confinement: tcp a port allowlist for the fetcher, and no listener anywhere
audit: gate log append only, read by the agent, written by the executor
gates: unattended mutate.remote host=grant group=deny all=deny
gates: unattended mutate.inventory deny
gates: unattended credential.access grant
gates: standing grants 3, each naming its hosts and its exact commands
confinement: landlock abi 6 on each helper process
confinement: tcp a port allowlist for the fetcher, and no listener anywhere
audit: gate log append only, read by the agent, written by the executor

Extensions

What you add, and where it runs.

25

Skills

A skill is a directory the agent reads. Thirteen ship with the package, and a marketplace installs more. The skill creator writes one with you.

my-tool →

13 shipped · marketplace

26

MCP servers

A stdio server runs in a confined host process on its own account, so a bad server reaches neither your credentials nor your hosts. An HTTP server connects without that process. enabledTools decides which tools the model sees. Every configured server sends its schemas in every prompt, which is where the cost is. Pause the ones you are not using, or set a server to send its tools only when you name it: the prompt then carries one line saying it exists, and the schemas arrive on that turn.

my-tool →

stdio · sse · streamableHttp

27

Data connectors

A connector reaches one data source with a capability class per operation, so reading your calendar and writing to it are two decisions. An MCP server cannot say that: its tools declare nothing, so a grant that unblocks a read unblocks every write. A connector installed from the catalog is a declaration, not code, and its credential names the hosts it may address — so a package cannot send your token somewhere you never reviewed. Set one to load only when you name it and its operations leave every other prompt.

data-connectors →

read allow · mutate.remote asks

28

Plugins and CLI apps

A Python entry point adds a tool. A CLI app exposes a program you already run.

my-tool →

entry points · agent plugins

29

Skills marketplace

The marketplace lists skills from a source you name. You install one from the WebUI, and you read it before you enable it. Connectors are in the same catalog, and their rows show every operation's class, the hosts a token could reach and the scopes it would carry — before the install button.

my-tool →

source · install · disable

Surfaces

Where you work, and what talks to it.

30

WebUI

One page holds chat, workspaces, inventory, secrets, diagrams, automations, approvals, the audit trail and settings.

webui →

127.0.0.1:8765

31

Workspaces

A file tree with more than one workspace and a switcher. Upload a folder after you review the plan. The preview renders text, images and PDFs, and offers a download for anything else.

webui →

type sniffed from the bytes

32

Chat apps

The same agent answers on ten channels. A DM sender pairs with a code before the agent replies.

chat-apps →

10 channels

33

API and SDK

An OpenAI-compatible endpoint answers programmatic callers. A Python SDK drives the loop in process.

openai-api →

/v1/chat/completions

34

Access control

The WebUI and the API need a token that the gateway issues with a lifetime. The gateway binds to localhost by default.

deployment →

127.0.0.1 · token ttl

35

Token and cost reporting

Every finished answer shows what it cost — tokens in, tokens out, the cache share, the wall time — and a `~` marks a total the provider did not report, so an estimate never reads as a measurement. Settings keeps a year of daily totals by what started the turn.

token-usage →

per turn · reported vs estimated

36

How you deploy decides the split

Four accounts make the kernel enforce the boundary. Without them the four processes share one uid, nanoinfra says so at startup, and one process can read another's memory.

deployment →

container · systemd · one uid

Nothing above this line
is a setting you can turn off

The gate, the split, the audit trail and the boundary around one person's files hold whether you configure them or not. What you configure is which actions they allow, and which host they allow them on.

Watch a refusal →