innerwall command line
The control-plane binary, innerwall, serves the agent gateway and the operator surface, and carries the command line that administers the same database. Every authoring and fleet command calls the same domain functions the operator surface's handlers call, so the two transports admit and write exactly the same things (ADR-0007, ADR-0021).
Conventions
- Flags come before positional arguments. Each command stops reading flags at its first positional argument, so write
innerwall flows list --since 1h <workload-id>, notinnerwall flows list <workload-id> --since 1h; the second form is refused with the command's usage line. Flags take one dash or two (-sinceand--sinceare the same flag). - The database. Every command except
ca initandversionopens Postgres.--database-urlnames it; without the flag,INNERWALL_DATABASE_URLdoes. A command with neither is refused:no database configured: set --database-url or INNERWALL_DATABASE_URL. - Direct writes. Authoring commands write Postgres directly and render there; the running control plane learns of the change through the database and pushes it to connected agents (ADR-0018). The command needs no running control plane, and none needs to be restarted.
- Help.
innerwall <command> <subcommand> -hprints a command's flags.innerwallwith no arguments prints the command list. - Identifiers. Workloads are named by their id (the UUID in their identity). Services, address groups, and rulesets are named by id or by name.
| Environment variable | Read by | Stands for |
|---|---|---|
INNERWALL_DATABASE_URL | every command that opens the database | --database-url |
INNERWALL_CA_DIR | serve, ca init | --ca-dir |
INNERWALL_SITE | serve | --site |
INNERWALL_GATEWAY_ADVERTISE_ADDRESS | serve | --gateway-advertise-address |
serve
innerwall serve [flags]Runs the agent gateway (enrollment, renewal, the sync stream, flow reports) and the operator surface (the REST/JSON façade and the embedded console, TLS only). Both listeners run in one process; replicas are stateless and share everything through Postgres (ADR-0017).
--listenDefault:8443- address for the agent gateway (gRPC over TLS)
--operator-listenDefault:8080- address for the operator surface (REST/JSON façade and console, TLS only)
--operator-tls-cert- operator listener certificate PEM (with
--operator-tls-key; default: a self-signed certificate persisted in<ca-dir>) --operator-tls-key- operator listener key PEM (with
--operator-tls-cert) --ca-dirDefault/var/lib/innerwall/ca- directory holding the signing authority (see
innerwall ca init) --init-ca- create the signing authority and server certificate if the CA directory holds none (development convenience)
--tls-hostsDefaultlocalhost,127.0.0.1- hosts for the server certificate generated by
--init-caand for a generated operator certificate --tls-certDefault<ca-dir>/server.crt- server certificate PEM
--tls-keyDefault<ca-dir>/server.key- server key PEM
--gateway-advertise-address- host:port agents reach the agent gateway at, shown in the console's enroll command; unset leaves the console's placeholder
--site- site label the console header shows
--leaf-ttlDefault24h- lifetime of issued workload credentials
--renewal-graceDefault72h- how long after its expiry a workload credential may still renew, and do nothing else; beyond it the workload re-enrolls
--flow-retentionDefault720h- age beyond which stored flow windows are deleted; totals are kept
--flow-retention-intervalDefault1h- period between flow retention runs
--migrate- apply pending database migrations before serving
--database-url- Postgres connection string
--tls-hosts takes effect only when a certificate is generated: the server certificate when --init-ca creates the authority, and the operator certificate when none is persisted or the persisted one has expired. A certificate that already exists is kept as it is, whatever the flag says now (multi-host evaluation).
migrate
innerwall migrate [--database-url URL]Applies pending database migrations. serve --migrate does the same before serving.
ca init
innerwall ca init [flags]Creates the file-backed signing authority and issues the agent gateway's server certificate from it, so agents verify the control plane with the same bundle that verifies their own credentials. It refuses a directory that already holds an authority. A deployment with several replicas creates the authority once and provisions the same directory on every replica (ADR-0017).
--ca-dirDefault/var/lib/innerwall/ca- directory to create the authority in
--hostsDefaultlocalhost,127.0.0.1- comma-separated DNS names and IPs for the server certificate
--root-ttlDefault87600h- lifetime of the root certificate
--server-ttlDefault8760h- lifetime of the server certificate
token
Provisioning tokens: what an agent presents, once, to enroll. A token is scoped to labels, expires, can be revoked, and is stored only as a digest (ADR-0016).
innerwall token mint [--name NAME] [--label key=value ...] [--ttl 720h]
innerwall token list
innerwall token revoke <token-id>mintprints the token once, on standard output, with its id, expiry, and labels on standard error. Every workload the token enrolls is assigned its labels; they are admitted against the label grammar (ADR-0022).listprints each token's id, prefix, name, state (valid,revoked,expired, orinvalid), expiry, use count, and labels.revokerevokes a token by id; enrollment refuses it from then on. Workloads it already enrolled are not affected.
--name- operator-facing name for the token
--label- label assigned to every workload the token enrolls, key=value (repeatable)
--ttlDefault720h- token lifetime
operator
The one operator's password and the operator tokens automation uses (ADR-0021).
innerwall operator set-password [--name NAME]
innerwall operator token mint [--name NAME] [--ttl DURATION]
innerwall operator token list
innerwall operator token revoke <token-id>set-passwordsets the operator password. It prompts twice without echo on a terminal, or reads one line from standard input when it is a pipe. A password shorter than 12 characters is refused.--namesets the display name the console shows; an empty one clears it. The command line on the host is the only place the password can be set: no endpoint sets or resets it.token mintprints an operator token once; only its digest is stored. Present it asAuthorization: Bearer <token>. Without--ttl(or with--ttl 0) the token does not expire.token listprints each token's id, prefix, name, state, expiry, and when it was last used.token revokerevokes one by id.
service
Reusable protocol and port sets, named by rules.
innerwall service create --name NAME --entry SPEC [--entry SPEC ...]
innerwall service update [--name NEW-NAME] [--entry SPEC ...] <id|name>
innerwall service delete <id|name>
innerwall service get <id|name>
innerwall service list--name- service name
--entry- protocol and ports, e.g.
tcp:5432ortcp:6000-6010,7000oricmp(repeatable; replaces all entries on update)
update writes against the version it reads first, so a service changed meanwhile is refused. A --name renames it; with no --entry its entries stay as they are.
address-group
Named sets of CIDRs, usable as rule peers.
innerwall address-group create --name NAME --cidr CIDR [--cidr CIDR ...]
innerwall address-group update [--name NEW-NAME] [--cidr CIDR ...] <id|name>
innerwall address-group delete <id|name>
innerwall address-group get <id|name>
innerwall address-group list--name- address group name
--cidr- member CIDR (repeatable; replaces all members on update)
update writes against the version it reads first. A --name renames the group; with no --cidr its members stay as they are.
ruleset
Rulesets as JSON documents, the same document form the operator surface accepts.
innerwall ruleset create -f FILE
innerwall ruleset update -f FILE <id|name>
innerwall ruleset delete <id|name>
innerwall ruleset get <id|name>
innerwall ruleset list-f - reads the document from standard input. update named on the command line is written against the version it reads first, so a ruleset changed meanwhile is refused; a document that carries its own id and no name argument is written unconditionally. Every write is admitted in full (every finding reported in one pass) and renders before it returns.
{
"name": "db-inbound",
"description": "who may reach the databases",
"scope": {"role": ["db"]},
"rules": [
{
"direction": "inbound",
"peers": [{"workloads": {"role": ["api"]}}, {"address_group": "corp"}, {"cidr": "10.20.0.0/16"}],
"services": ["postgres"],
"entries": [{"protocol": "tcp", "ports": ["9187"]}]
}
]
}| Field | Holds |
|---|---|
name, description, enabled | The ruleset's name, description, and enabled switch (enabled when omitted). |
scope | The destination: a selector, key to the values it admits. Keys are ANDed, a key's values ORed. |
rules[].direction | inbound, the only direction admitted (ADR-0010). |
rules[].peers | Each peer is exactly one of workloads (a selector), address_group (a name or id), or cidr. |
rules[].services, rules[].entries | Named services (name or id), inline entries (protocol and ports, where no ports means every port), or both. |
rules[].enabled, rules[].description | The rule's own switch and description. |
workload
innerwall workload list
innerwall workload counts
innerwall workload status <workload-id>
innerwall workload set-labels --label key=value [--label key=value ...] <workload-id>
innerwall workload set-mode <workload-id> visibility|simulation|enforced
innerwall workload resend-snapshot <workload-id>listprints every workload's id, hostname, labels, mode, sync state (withENFORCEMENT REMOVEDwhen its owned table is recorded absent), applied and latest policy versions, and when it was last seen.countsprints the fleet's size:removed, then each sync state, then the total. A removed workload is counted inremovedalone, so the lines sum to the total. It is the readGET /api/v1/workloads/countsserves.statusprints one workload in full: mode, sync state, the owned table's state, applied and latest versions, last seen on the control channel, last flow report, last snapshot sent, last acknowledgment, last failed apply, credential expiry and any late renewal, agent version, dropped flow records, source overruns, clock skew, addresses, host facts, and listening services.set-labelsreplaces the workload's whole label set and renders. The labels are admitted against the grammar (ADR-0022).set-modechanges one workload's mode, as a recorded mode change of exactly that workload, and renders. It does not consult the simulation review: the review's verdict and its acknowledgment gate are in the console's promote flow only (promotion and enforcement).resend-snapshotdirects the workload's agent to reconnect, so its new stream begins with a snapshot. Delivery is not confirmed: thelast snapshotinstant inworkload statusadvances when the agent has reconnected (states).
policy
innerwall policy render
innerwall policy show <workload-id>renderforces a render of every workload and prints which changed and to what version. Every write already renders; this is for recovery after a render failed, and for inspection.showprints a workload's persisted rendered policy as JSON: its version, mode, and rules with their resolved peers and provenance.
flows
Stored flow windows, evidence gaps, and totals, read through the same queries as the operator surface (ADR-0019).
innerwall flows list [--since 24h] [--until T] [--decision D] [--limit 200] <workload-id>
innerwall flows rollup [--label key=value ...] [--decision D] [--since 24h] [--until T] [--group-by G ...]
innerwall flows totals [--decision D] <workload-id>
innerwall flows gaps [--label key=value ...] [--workload ID] [--since 24h] [--until T] [--limit 500]listprints one workload's windows, newest first: window, peer, source, service, decision, rule, connections, and bytes.rollupwithout--group-byaggregates by peer and service over the workloads the labels select (every workload when none is given). With--group-byit is the operator surface's grouped rollup, with the same groupings, ordering, and limit.totalsprints a workload's totals since first seen; these outlive flow retention.gapsprints the evidence gaps that intersect the range, newest first (gap kinds).
--sinceDefault24h- start of the range: a duration before now or an RFC 3339 time
--untilDefaultnow- end of the range: a duration before now or an RFC 3339 time
--decisionDefaultall- only this decision:
observed,allowed,would_block, orblocked(list,rollup,totals) --label- label key=value selecting the workloads in scope (repeatable, ANDed; none selects every workload) (
rollup,gaps) --limitDefault200;500forgapslist: maximum rows, newest window first;rollup --group-by: the most groups shown, the rest counted in the totals;gaps: the most gaps shown--group-by- the operator surface's grouped rollup instead of the peer-and-service one:
rule,rule,peer,src,dst,dst,service, orpeer,service --endpointDefaultdst- with
--group-by: which end of a flow the scope selects:dst(the flows its workloads received) oreither(also the flows they sent) --orderDefaultconnections- with
--group-by:connectionsorrecent --service- with
--group-by: only this service,<protocol>/<port>oricmp --workloadrollup --group-by: only this workload's flows;gaps: only this workload's gaps
version
innerwall versionPrints the build's version (versioning). The dev command exists only in builds made with the dev build tag, for development; release builds do not carry it.