Changelog: November 2026

This month, we added environment governance with a Disable manual IaC sync setting that keeps AI coding agents from altering production infrastructure, while IaC sync keeps working through repository webhooks and CI automation tools. We expanded cost reporting with an Untagged costs page that shows the resources behind Unmanaged spend and generates the commands to tag them, and every cost chart now drills down on click. ECS and Fargate task apps keep their execution history past ECS's one-hour retention, and every Nullstone app module now reports the environment values your app actually received. Read on for details.

November 1, 2026
Brad Sickles
Brad Sickles
Co-founder and CEO
Changelog: November 2026

Overview

# Product

- Protect Production from AI Agents
- Untagged Costs: Find and Fix Unattributed Spend
- Click to Drill into Any Cost Chart
- Execution History for ECS and Fargate Jobs
- Real Environment Variables Once Launched
- Fixes & Smaller Improvements

## Protect Production from AI Agents

An AI coding agent working in a developer's checkout can edit `.nullstone/` files and run `nullstone iac sync` in the same turn, with the developer's own credentials, before anyone has reviewed the change.
Until now, nothing stood between that agent and your production infrastructure.

Each environment now has a **Disable manual IaC sync** governance setting (Environment > Settings > Governance).
With it on, no agent, and no person, can alter the environment's infrastructure by running `nullstone iac sync` from a machine.
IaC sync still works through the paths you already trust: the connected repository's webhooks (push, tag, release, and pull request events) and `nullstone iac sync` running inside a CI automation tool such as GitHub Actions, CircleCI, or GitLab.
Every change to production goes through your repository and your pipeline, where it is reviewed before it lands.

Turn it on for production and leave it off for dev and sandbox environments where an agent iterating quickly is the point.

What's new:

- **The toggle** on the environment settings page, editable by stack architects and owners. It is set in the UI or through the environment API, not in `.nullstone/` files, so an agent editing IaC cannot switch it off
- **Syncs show how they were started.** `nullstone iac sync` (CLI 0.0.210) reports the CI tool it runs under, so activity views show `manual` for a person or agent, `via GitHub Actions` (or the detected tool) for a pipeline, and the event name (`push`, `tag`, `release`) for a webhook
- **A rejected sync explains itself.** The CLI prints the server's message and exits non-zero, so an agent reading the output learns to push a branch instead:

```
Manual IaC sync is disabled for environment "prod" in stack "primary".
Push the change to the connected repository
or run `nullstone iac sync` from your CI pipeline instead.
```

CI detection reads the CI tool's environment variables (`GITHUB_ACTIONS`, `CIRCLECI`, `GITLAB_CI`, and so on), so this is a guardrail against an agent reaching for `iac sync` on its own, not a security boundary against a determined insider.
Pair it with a least-privilege API key for agents.
[Protect production from AI agents](https://docs.nullstone.io/gitops/best-practices.html#lock-production-to-the-pipeline)

## Untagged Costs: Find and Fix Unattributed Spend

Last month's cost reporting rolled spend with no `Stack` tag into an **Unmanaged** bucket so totals matched your bill.
This month, you can do something about that bucket.

Click **Unmanaged** on the Dashboard to open the new **Untagged costs** page: untagged spend over time, plus a ranked table of the resources behind it with filters by provider, account, service, charge category, and resource id.
Select one or more rows, then:

- **How to tag.** Pick the stack, environment, and block the resources belong to. The dialog shows the exact `Stack`, `Env`, and `Block` tags (lowercase labels on GCP), links to each resource in the cloud console, and generates one `aws resourcegroupstaggingapi tag-resources` or per-type `gcloud … add-labels` command that tags all of them at once
- **Mark untaggable.** Spend that can never carry a tag (support plans, taxes, a billing-only account) moves into a new **Untaggable** bucket with a note explaining why. A rule can match just the selected resources, everything from a service in a cloud account, or an entire account. Rules apply to history as well as new spend, and totals still reconcile. Any org member can see rules; creating or removing one requires the Org Architect role

Nullstone classifies non-usage charges such as credits, taxes, and support as Untaggable automatically, so the Unmanaged number is the one worth driving down.

With Cost Explorer alone, AWS reports spend by service, so the page lists services rather than the resources behind them.
Connect an AWS Data Export to see individual resources. GCP cost providers report resources from the BigQuery billing export you already connected.

- [Tagging and untagged costs on AWS](https://docs.nullstone.io/integrations/cloud-providers/aws.html#untagged-costs)
- [Labeling for cost attribution on GCP](https://docs.nullstone.io/integrations/cloud-providers/gcp.html#tagging)

## Click to Drill into Any Cost Chart

Every cost chart and breakdown table is now a way to navigate.
Click a chart band or a breakdown row to open that stack, environment, block, or workspace's own cost view.
The period, cost measure (amortized or billed), and chart mode travel with you, so the next page opens where you left off, and the browser's back button returns you to the previous view.

Hiding a series moved to a per-row eye icon, so a click never means two things.
SKU rows and the folded "Other" row are leaves and ignore the click.
The Unmanaged and Untaggable rows open the Untagged costs page.

## Execution History for ECS and Fargate Jobs

ECS discards stopped tasks about an hour after they stop.
For task apps, including cron-triggered jobs, that meant a nightly run had vanished from the executions list and the ECS console by the time anyone looked, leaving CloudWatch Logs as the only trace.

Cluster modules now record every ECS task state change into a `<cluster>-executions` log group, and Nullstone merges that history with live tasks.

What's new:

- **Runs stay visible** in the app's executions list for `executions_retention_in_days` (default 30), each labeled with the image and revision it actually ran, even after a newer deploy
- **`nullstone status` works for task apps.** It previously failed with `Service cannot be empty`. The summary now shows running count, execution count, last run, and last result, and `--detail` lists each execution with start, stop, status, version, exit code, and failure reason (CLI 0.0.209)

Upgrade the cluster module to turn this on: `aws-fargate` 0.9.0 or `aws-ecs` 0.4.0, and `aws-fargate-namespace` or `aws-ecs-namespace` 0.3.0 for preview environments.
Task modules and apps need no change. Clusters on older versions keep showing live tasks only.

- [Fargate Cluster](https://app.nullstone.io/registry/modules/nullstone/aws-fargate)
- [ECS Cluster](https://app.nullstone.io/registry/modules/nullstone/aws-ecs)
- [Fargate Namespace](https://app.nullstone.io/registry/modules/nullstone/aws-fargate-namespace)
- [ECS Namespace](https://app.nullstone.io/registry/modules/nullstone/aws-ecs-namespace)

## Real Environment Variables

Last month, we rebuilt the Environment Variables screen to show the value your app actually received instead of **(generated)**.
That screen could only show what the app module reported, and most modules were not reporting yet.

This month, every Nullstone app module reports its applied values.
Once an app is launched, the screen shows the real environment variables, pulled directly from the infrastructure state of the last apply: the final value of every variable, including the ones that modules and capabilities inject and the platform built-ins such as `GOOGLE_*`.
A variable with no value to show still says why (not launched yet, secret, runtime reference), and a variable you have changed since the last apply shows both the applied value and the pending one.

This requires updating the app's infra module.
Upgrade to the latest version of the app module and apply; the screen fills in on that infra update.
The full list of updated modules is under **App Modules Report Applied Environment Values** in the Catalog section below.

## Fixes & Smaller Improvements

- **Deploys use the module the workspace actually applied.** Swapping a block's module (for example `aws-lambda-service` to `aws-lambda-container-service`) and deploying before the next apply failed with `required output missing (name=artifacts_bucket_name)`, because the deploy resolved the module from the block instead of the last applied run. Deploy, logs, status, and metrics now all resolve from the workspace's last finished run, matching the CLI
- **Output-only plans show as changes, not "No changes".** A destroy whose resources were already gone still plans an output change and runs a short apply to clean up state. The concise plan view showed a green **No changes** under a running badge, which looked stuck. Output changes now render in a "Changes to Outputs" section with an outputs pill, and an apply still in flight shows **Applying…**
- **Laptop deploys are recorded as manual.** A CI-detection bug recorded every `nullstone deploy`, `launch`, and `release` run without CI variables as Codeship automation (CLI 0.0.210)
- **CLI profile files are private.** `~/.nullstone/<profile>/`, the API key, and the Terraform credentials file are created readable only by the owner, and existing files are tightened on next use (CLI 0.0.208)

# Catalog

### App Modules Report Applied Environment Values

The Environment Variables screen (see **Real Environment Variables Once Launched** above) reads the value your app actually received from an `env` platform data record the module emits.
Every Nullstone app module now emits it, using the new layered `ns_env_layout`, `ns_env_values`, and `ns_env_platform_data` data sources from the `ns` provider 0.13.
Upgrade to the latest version of your app module and apply; the screen fills in on that infra update.

- **AWS:** [Fargate Service](https://app.nullstone.io/registry/modules/nullstone/aws-fargate-service), [Fargate Task](https://app.nullstone.io/registry/modules/nullstone/aws-fargate-task), [ECS Service](https://app.nullstone.io/registry/modules/nullstone/aws-ecs-service), [ECS Task](https://app.nullstone.io/registry/modules/nullstone/aws-ecs-task), [EKS App](https://app.nullstone.io/registry/modules/nullstone/aws-eks-app), [EKS Job](https://app.nullstone.io/registry/modules/nullstone/aws-eks-job), [Lambda Service](https://app.nullstone.io/registry/modules/nullstone/aws-lambda-service), [Lambda Container Service](https://app.nullstone.io/registry/modules/nullstone/aws-lambda-container-service), [Batch Fargate Job](https://app.nullstone.io/registry/modules/nullstone/aws-batch-fargate-job), [Beanstalk App](https://app.nullstone.io/registry/modules/nullstone/aws-beanstalk-app), [S3 Site](https://app.nullstone.io/registry/modules/nullstone/aws-s3-site), [Power BI Gateway](https://app.nullstone.io/registry/modules/nullstone/aws-powerbi-gateway)
- **GCP:** [Cloud Run Service](https://app.nullstone.io/registry/modules/nullstone/gcp-cloudrun-service), [Cloud Run Job](https://app.nullstone.io/registry/modules/nullstone/gcp-cloudrun-job), [GKE Service](https://app.nullstone.io/registry/modules/nullstone/gcp-gke-service), [GKE Job](https://app.nullstone.io/registry/modules/nullstone/gcp-gke-job), [Cloud Function](https://app.nullstone.io/registry/modules/nullstone/gcp-function), [GCE Server](https://app.nullstone.io/registry/modules/nullstone/gcp-gce-server), [GCS Site](https://app.nullstone.io/registry/modules/nullstone/gcp-gcs-site), [Composer Environment](https://app.nullstone.io/registry/modules/nullstone/gcp-composer-env)
- **Azure:** [Container App](https://app.nullstone.io/registry/modules/nullstone/azure-container-app), [AKS Service](https://app.nullstone.io/registry/modules/nullstone/azure-aks-service), [AKS Job](https://app.nullstone.io/registry/modules/nullstone/azure-aks-job), [Function](https://app.nullstone.io/registry/modules/nullstone/azure-function)

Custom app modules get the same pattern from `nullstone modules generate` (CLI 0.0.207): the generated `env_vars.tf` aggregates variables and secrets through the layered data sources and reports them to Nullstone.
Set `local.env_platform` to the module's runtime platform and the module validates.

### CloudWatch Logs IAM Policies Ready for AWS's 2027 Change

From April 26, 2027, AWS requires IAM statements that grant log group actions (`FilterLogEvents`, `StartQuery`, `DescribeLogStreams`, and others) to name the log group ARN.
A log stream ARN (`…:log-group:<name>:*`) will only grant stream actions such as `PutLogEvents` and `GetLogEvents`.

We audited all 135 AWS modules. Three policies granted log group actions against a stream ARN only, and each now lists both ARN forms:

- **`terraform-aws-logs` 0.2.3 and 0.3.1**, the log reader used by most AWS app modules. 0.3.1 also adds `moved` blocks so 0.1.x consumers upgrade without recreating the log reader
- **`aws-cloudwatch-log-group-access` 0.0.3**
- **`aws-beanstalk-app` 0.5.1**

`aws-eks-standard` 0.0.24, `aws-eks-auto` 0.1.4, `aws-batch-fargate-job` 0.3.1, and the Lambda and S3 site scaffolds now pin the fixed logs module; the ECS, Fargate, Lambda, and S3 app modules pick it up on their next run.
Nothing changes at runtime today. Apply the latest versions before the deadline and log access keeps working after it.

- [CloudWatch Log Group Access](https://app.nullstone.io/registry/modules/nullstone/aws-cloudwatch-log-group-access)
- [Beanstalk App](https://app.nullstone.io/registry/modules/nullstone/aws-beanstalk-app)
- [EKS Standard](https://app.nullstone.io/registry/modules/nullstone/aws-eks-standard)
- [EKS Auto](https://app.nullstone.io/registry/modules/nullstone/aws-eks-auto)
- [Batch Fargate Job](https://app.nullstone.io/registry/modules/nullstone/aws-batch-fargate-job)
- [Lambda App Scaffold](https://registry.terraform.io/modules/nullstone-modules/lambda-appscaffold/aws/latest)
- [S3 Site App Scaffold](https://registry.terraform.io/modules/nullstone-modules/s3site-appscaffold/aws/latest)

### Self-Hosted HashiCorp Vault on AWS

`aws-ec2-vault-cluster` runs Vault CE on an EC2 Auto Scaling Group with Raft storage, KMS auto-unseal, an internal load balancer on `vault.internal`, scheduled S3 snapshots, and a rolling instance refresh that joins the new node before the old one leaves.
Apps connect through the `aws-vault-access` capability: each app logs in with its own IAM role and mints short-lived tokens scoped to its own tenant path, so an app never holds a token that spans tenants.
Launched in a stack's shared previews environment, one cluster serves every preview environment with secrets scoped per environment.
The `aws-vault-admin` and `gcp-vault-admin` blocks write the app roles for each auth method.

- [EC2 Vault Cluster](https://app.nullstone.io/registry/modules/nullstone/aws-ec2-vault-cluster)
- [Vault Access](https://app.nullstone.io/registry/modules/nullstone/aws-vault-access)
- [Vault Admin (AWS)](https://app.nullstone.io/registry/modules/nullstone/aws-vault-admin)
- [Vault Admin (GCP)](https://app.nullstone.io/registry/modules/nullstone/gcp-vault-admin)