1. Docs
  2. Deploy & operate
  3. innerwall command line
GitHub
Rendered from innerwall v0.4.1

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>, not innerwall flows list <workload-id> --since 1h; the second form is refused with the command's usage line. Flags take one dash or two (-since and --since are the same flag).
  • The database. Every command except ca init and version opens Postgres. --database-url names it; without the flag, INNERWALL_DATABASE_URL does. 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> -h prints a command's flags. innerwall with 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 variableRead byStands for
INNERWALL_DATABASE_URLevery command that opens the database--database-url
INNERWALL_CA_DIRserve, ca init--ca-dir
INNERWALL_SITEserve--site
INNERWALL_GATEWAY_ADVERTISE_ADDRESSserve--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-ca and 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>
  • mint prints 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).
  • list prints each token's id, prefix, name, state (valid, revoked, expired, or invalid), expiry, use count, and labels.
  • revoke revokes 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-password sets 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. --name sets 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 mint prints an operator token once; only its digest is stored. Present it as Authorization: Bearer <token>. Without --ttl (or with --ttl 0) the token does not expire.
  • token list prints each token's id, prefix, name, state, expiry, and when it was last used.
  • token revoke revokes 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:5432 or tcp:6000-6010,7000 or icmp (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.

web-to-db.json
{
  "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"]}]
    }
  ]
}
FieldHolds
name, description, enabledThe ruleset's name, description, and enabled switch (enabled when omitted).
scopeThe destination: a selector, key to the values it admits. Keys are ANDed, a key's values ORed.
rules[].directioninbound, the only direction admitted (ADR-0010).
rules[].peersEach peer is exactly one of workloads (a selector), address_group (a name or id), or cidr.
rules[].services, rules[].entriesNamed services (name or id), inline entries (protocol and ports, where no ports means every port), or both.
rules[].enabled, rules[].descriptionThe 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>
  • list prints every workload's id, hostname, labels, mode, sync state (with ENFORCEMENT REMOVED when its owned table is recorded absent), applied and latest policy versions, and when it was last seen.
  • counts prints the fleet's size: removed, then each sync state, then the total. A removed workload is counted in removed alone, so the lines sum to the total. It is the read GET /api/v1/workloads/counts serves.
  • status prints 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-labels replaces the workload's whole label set and renders. The labels are admitted against the grammar (ADR-0022).
  • set-mode changes 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-snapshot directs the workload's agent to reconnect, so its new stream begins with a snapshot. Delivery is not confirmed: the last snapshot instant in workload status advances when the agent has reconnected (states).

policy

innerwall policy render
innerwall policy show <workload-id>
  • render forces 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.
  • show prints 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]
  • list prints one workload's windows, newest first: window, peer, source, service, decision, rule, connections, and bytes.
  • rollup without --group-by aggregates by peer and service over the workloads the labels select (every workload when none is given). With --group-by it is the operator surface's grouped rollup, with the same groupings, ordering, and limit.
  • totals prints a workload's totals since first seen; these outlive flow retention.
  • gaps prints 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, or blocked (list, rollup, totals)
--label
label key=value selecting the workloads in scope (repeatable, ANDed; none selects every workload) (rollup, gaps)
--limitDefault200; 500 for gaps
list: 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, or peer,service
--endpointDefaultdst
with --group-by: which end of a flow the scope selects: dst (the flows its workloads received) or either (also the flows they sent)
--orderDefaultconnections
with --group-by: connections or recent
--service
with --group-by: only this service, <protocol>/<port> or icmp
--workload
rollup --group-by: only this workload's flows; gaps: only this workload's gaps

version

innerwall version

Prints 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.