Skip to Content

Stack

Where: Stack in the sidebar (#/stack).

Stack with the Declared · Observed · Verified header, a connected GitHub source slot, the shadow banner, and the Security Plane cards with Observed and Verified lines.
Save as public/guide/stack.png

Stack is the blueprint view of your toolchain. It answers which teams actually run secret scanning? without a Slack thread. For each tooling category it shows three facts side by side, never blended:

  • Declared: what your environment profile says. That is the environment-profile.yaml file at the root of your platform repo, where you declare the tools you run and the behaviors you attest to. Every agent reads it before acting.
  • Observed: what a read-only source running in your cluster saw, with the source and how long ago.
  • Verified: the status your latest gap analysis gave the category: verified, claimed, disputed or missing.

A declaration is a claim. An observation is evidence. The gap between them is the point of the screen.

You do not edit anything here. You edit the profile in Git, through your normal review process, and you connect sources in your own cluster; Stack shows what TruStacks read.

What you see

Declared · Observed · Verified

The header above the categories:

  • Application: a picker, when you have more than one. It scopes the Observed and Verified lines to that Application’s repos and its latest gap analysis.

  • Source slots: one per source your runner reports, for example github, with its status, server version, the age of its last sweep, and how many observations and audited calls it made (and how many calls were refused or observations quarantined). Statuses:

    Slot saysMeaning
    connected · read-only verifiedThe source started, and every tool its server offered was on our read-only allowlist.
    refused — the server offered a tool we do not allowThe runner refused to start the source. Nothing was called.
    last sweep failedThe last sweep errored. The cards keep showing the last good sweep, with its age, rather than going blank.
    credential missingThe source is on, but its Secret is not there.

    With no source reporting, the header says No signal source connected yet.

  • Shadow · not applied: your current coverage and tier, and what they would be if the observations counted (or Observations would not change it.). Nothing changes until the evidence rules go live. The banner is shown so you can see the effect before it lands; it never changes your score.

  • Also observed, not connected to any Application: repos the source watched (through extraRepos) that TruStacks does not govern.

Planes

The twelve categories are grouped by the platformengineering.org reference architecture’s planes:

PlaneCategoriesShown as not modelled
Developer Control PlaneTicketing / change-mgmtDeveloper portal / catalog, Workload spec, IDE / CDE, AI coding & review
Integration & Delivery PlaneCI/CD platform, Container registry, GitOps controllerPlatform orchestrator, Dependency-update bots
Resource PlaneService mesh / ingressClusters / compute, IaC, Databases / storage, DNS
Observability PlaneObservabilityFinOps, Incident management
Security PlaneImage scanning, SAST / SCA, Secret scanning, SBOM + signing, Secrets management, Compliance evidenceAdmission policy, IAM, Runtime security

A not modelled chip is part of the reference architecture that TruStacks does not model yet. It is never shown as something you are missing.

Tooling categories

A card for each category. The headline is what you declared, in one of these states:

Card saysMeaning
The provider name (declared)You declared at least one tool. The primary one is shown.
not declaredThe profile was read, and this category is empty. The agents have no tool to ground a pipeline step in.
flagged by your last auditThe profile could not be read here, but your most recent gap analysis found this category missing.
unknownThe profile could not be read here and no audit has flagged the category.

For a category that is not declared, the card explains what that costs:

  • Needed by N rules, lowers your maturity coverage, with the rule ids and suggested tools from your last gap analysis; or
  • Your last gap analysis found no rule that needs this; or
  • Run a gap analysis to see what needs this → if you have none.

Under the headline, every card has two more lines:

  • Observed: each observation as a short fact, its status, the source, the repo and its age. For example GitHub Actions: 14 runs in 30d, Dependabot alerts: disabled, Semgrep: results uploaded, Secret scanning: 2 open alerts. A status is one of:

    • observed: we looked, and it holds;
    • absent: we looked, and it does not, for example the feature is turned off. This is a real finding;
    • unknown: could not look, for example the token lacks a permission or GitHub rate-limited us. It is our blind spot, not your gap, and it never counts against you.

    With nothing to show, the line says no source connected, nothing reported yet, or no source can observe this yet.

  • Verified: the status from your latest gap analysis, or no gap analysis yet. If an observation would change it, a hint follows: would be verified (shadow, not applied), with the evidence rule and why.

Today one source exists, GitHub, and it can observe four categories: CI/CD platform, SAST / SCA, Secret scanning and Image scanning. On those cards, until a source is connected, Connect a source → opens the recipe below.

Connect a source

Connect a source → shows the recipe for the GitHub source. It never offers a token field: the token stays in your cluster and never reaches TruStacks.

  1. Create a fine-grained personal access token. Repository access: only the repos you connect. Repository permissions, each Read-only: Actions, Contents, Metadata, Pull requests, Issues, Dependabot alerts, Code scanning alerts, Secret scanning alerts. No write permission anywhere.

  2. Store it in your runner’s namespace. printf is a shell builtin, so the token never becomes a process argument; --from-literal would put it in kubectl’s arguments, where anyone who can list processes (ps) could read it:

    read -rs GH_TOKEN && \ printf '%s' "$GH_TOKEN" | kubectl -n <runner-namespace> create secret generic trustacks-mcp-github \ --from-file=token=/dev/stdin && unset GH_TOKEN
  3. Turn the source on:

    helm upgrade trustacks-runner oci://ghcr.io/trustacks/charts/runner \ --version <version> \ -n <runner-namespace> --reset-then-reuse-values \ --set mcpSignals.enabled=true \ --set mcpSignals.sources.github.enabled=true

The runner needs HTTPS egress to api.github.com. Observations appear after its first sweep, which runs when the pod starts and then every six hours. It needs runner 0.2.14-rc27 or later. Every value is in the Runner Helm chart reference.

The app’s recipe uses the same OCI chart with placeholders: <release>, <runner-namespace> and --version <your-runner-version>. Replace the version with the one your runner runs now (Runners shows it). Without --version, Helm installs the newest stable chart and can downgrade a pre-release runner. The full wizard, which fills these in for a runner you pick and waits for its report, lives on Signals › Connect a source.

A fine-grained token has exactly one resource owner (a user or an organization). Repos owned by two different owners need two tokens, and a runner reads one token per source today.

Behaviors (self-attested)

The practices: block of your profile, one line per key, marked attested (true) or not attested.

Tool-actions packs

A short note on how the DevOps Engineer pins each tool’s GitHub Action to an immutable commit SHA from the published packs, with a link, See the packs and their pins, to the tool-actions directory of trustacks-policy. The link shows even when your profile cannot be loaded. See knowledge packs.

What it means

  • Declaring is configuration. Listing trivy under image_scanning tells the DevOps Engineer to add a Trivy step to your pipeline, and only tools you declare get steps. The agents never add tools you did not declare; recommendations go into the gap analysis instead.
  • A category you leave out is not neutral. Rules that depend on it count as unsatisfied, so the score understates what you run.
  • Behaviors are claims. Each true under practices: is a statement about how your pipeline behaves. TruStacks counts a claim at half credit until it can verify it from evidence, and at no credit if the evidence contradicts it. See Verified, claimed and disputed.
  • Credentials never live here. The profile names tools, not secrets, and a source’s token lives in a Secret in your cluster.
  • An observation is evidence, not a verdict. It moves a row from claimed to verified only through an evidence rule that names one source, one category, one provider and the exact condition. For example, CI/CD platform github_actions would be verified when a run on the default branch ran and passed within 30 days. A Semgrep upload does not verify a declared CodeQL. In this release those rules run in shadow: you see what they would do, and your score does not change.
  • Observation is read-only and model-free. The runner runs GitHub’s official MCP server in read-only mode, refuses its write tools, and runs a fixed list of read calls. No model decides what to call, and nothing a tool returns is ever turned into the next call. See Integration model.

What to do here

  1. If a card says not declared for a tool you actually run, add it to environment-profile.yaml in your platform repo and merge.
  2. If you declared a tool and the source observes it absent (for example Secret scanning: disabled), either turn it on or correct the declaration. The observation is what an auditor would find.
  3. Uncomment a practices: line only once it is true of your pipeline.
  4. Run a new gap analysis to see the effect on your score.

The file format, every category and the five behavior keys are in the environment profile reference.

How it connects

  • The profile is read by every proposal and every gap analysis.
  • What it declares, checked against Rules, becomes your Maturity score.
  • Open alerts the GitHub source observes (Dependabot, code scanning, secret scanning) on your connected repos arrive in Signals as findings.

Beta limits

  • One profile on this screen. If your Applications use different platform repos, Stack cannot yet tell which profile to show, says so, and falls back to what your last audit found. The Application picker scopes the Observed and Verified lines, not the Declared headline.
  • Shadow only. Observations do not change your score in this release.
  • One source, four categories. GitHub is the only source. The other eight categories say no source can observe this yet. Showing tools nobody declared (an undeclared cell) and an org-wide matrix across Applications are planned.
  • The note under Behaviors says the scorer counts every true as covered. That is out of date: a true the evidence cannot confirm counts half, and one the evidence contradicts counts nothing.
  • Only some categories carry scoring rules today. Declaring the others still guides the agents and shows here, but may not move your score. The Maturity page shows exactly which rows are scored.
Last updated on