---
date: 2026-09-30T00:00:00.000Z
tags:
  - deployments
  - ui
  - providers
  - security
  - api keys
  - permissions
  - cli
  - agent
  - entity hooks
  - services
  - service specification
  - api
  - api reference
  - scopes
  - kubernetes
  - approvals
  - monthly
toc_max_heading_level: 2
doc_id: d3823963-b42e-441f-ac8f-0bd2fef620ef
description: >-
  September updates: the redesigned deployment page arrives as a rollout you
  control, API keys can hold exactly the permissions they need, entity hooks can
  hand data back to the entity they're gating, packages pin a service
  specification together with its artifacts, you can push assets to ECR with an
  IAM role instead of long-lived keys, and new CLI, agent, and scopes releases
  bring readable Kubernetes object names and one-time scheduled tasks.
keywords:
  - deployment page
  - deployment view
  - deployment stages
  - deployment group
  - blue/green
  - fast rollback
  - finish deployment
  - deployment logs
  - deployment catalog
  - walkthrough
  - rollout
  - new view
  - np asset push
  - asset repository
  - ECR
  - IAM role
  - OIDC
  - GitHub Actions
  - GitLab CI
  - docker registry
  - no-login
  - CI/CD
  - API keys
  - fine-grained permissions
  - custom permissions
  - grants
  - inherits
  - machine users
  - entity hooks
  - callback_body
  - hook request
  - before-hook
  - repository_url
  - packages
  - package revision
  - bill of materials
  - artifacts
  - artifact revision
  - oci image
  - specification snapshots
  - service specification
  - services api
  - api reference
  - scopes
  - kubernetes
  - health check
  - probes
  - custom domain
  - additional ports
  - resource naming
  - naming strategy
  - scheduled tasks
  - run once
  - np_request
  - np application patch
  - agent
  - NP_WORKER_SECURITY
  - sign in
  - checklists
  - on_checklist_fail
  - delete application
title: September 2026
slug: september-2026
canonical: 'https://docs.nullplatform.com/changelog/september-2026'
---
September updates: the redesigned deployment page arrives as a rollout you control, API keys can hold exactly the permissions they need, entity hooks can hand data back to the entity they're gating, packages pin a service specification together with its artifacts, you can push assets to ECR with an IAM role instead of long-lived keys, and new CLI, agent, and scopes releases bring readable Kubernetes object names and one-time scheduled tasks.

## ✨ The deployment page, redesigned

The page you land on after starting a deployment was rebuilt, for single deployments and deployment groups alike. Now you can see **where a deployment is** at a glance and understand **what happened in each stage**, without piecing it together from one long log stream. The run is laid out as a line of stages, each with its own outcome, so when something stalls you know which stage it stopped in and why. Click any completed stage to go back to it: the panel shows what that stage did, and the logs narrow to the minutes that matter.

Take the walkthrough below, the same one the platform offers beside the page title:

<GuidedTour
  alt="The redesigned deployment page, recreated as an HTML scene with a guided walkthrough"
  callout={{
    anchor: 'deployment-whats-new',
    title: 'The deployment page got an update',
    badge: 'New view',
    summary: "The deployment's stages are laid out in order, each with its outcome. Click a completed one to see what happened in it.",
    footerQuestion: 'Something not working?',
    footerAction: 'Turn off beta',
  }}
  steps={[
    {
      title: 'The deployment at a glance',
      body: 'A summary of the deployment: what is being deployed, where it is going, and its status, along with the build and the activity history.',
      anchor: 'deployment-headline',
      placement: 'bottom',
    },
    {
      title: 'Every stage, in order',
      body: "This line shows the deployment's progress through its stages, with the current one highlighted. Click a completed stage to see its details.",
      anchor: 'deployment-stations',
      placement: 'bottom',
    },
    {
      title: 'One stage at a time',
      body: 'Here you see the current stage in detail. Select another completed stage from the line to see that one instead.',
      anchor: 'deployment-canvas',
      placement: 'bottom',
    },
    {
      title: 'Logs for this stage',
      body: 'The logs for the current stage. While the stage is running, they tail live.',
      anchor: 'deployment-logs',
      placement: 'top',
    },
  ]}
>
  <DeploymentScene />
</GuidedTour>

### You can switch back anytime

The new page reaches your organization as a rollout you can walk back: if it doesn't work for you, **Previous version** beside the page title puts you back on the old one right away. 

👉 See [Deployment view](/docs/deployments/deployment-view).

## ✨ API keys with exactly the permissions they need

An API key's grant used to be a role on a resource, so a CI pipeline that needed two actions got every action of the closest role. A grant can now start from roles, adjust them permission by permission, or skip roles entirely and hold only the permissions you tick. Either way, you can only hand out what you could grant yourself on that resource.

It's all in the **New API key** form, under **Platform settings > API keys**. Take the walkthrough:

<GuidedTour
  alt="The New API key form, recreated as an HTML scene with a guided walkthrough"
  steps={[
    {
      title: 'Choose where the grant applies',
      body: 'Each row is one grant. The key gets its permissions on this resource and everything under it.',
      anchor: 'api-key-grant-resource',
      placement: 'bottom',
    },
    {
      title: 'Start from roles',
      body: 'The roles you pick preselect the permissions. A customized pill marks a grant you adjusted by hand.',
      anchor: 'api-key-grant-role',
      placement: 'bottom',
    },
    {
      title: 'Customize permissions',
      body: 'Open the full list to tick or untick single permissions on top of the roles. With no role selected, the permissions you tick are the whole grant, and the Role field shows Custom.',
      anchor: 'api-key-grant-permissions',
      placement: 'bottom',
      align: 'end',
    },
    {
      title: 'Tick permissions one by one',
      body: 'Each box is one action on one kind of resource. Boxes outside what you can hand out show disabled, and the footer counts what the key may do.',
      anchor: 'api-key-permissions-matrix',
      placement: 'top',
      align: 'end',
    },
  ]}
>
  <ApiKeyScene />
</GuidedTour>

Through the API, the same three options are `role_slug` or `role_id`, `inherits` with `actions.add` and `actions.remove`, or a custom `actions` list.

👉 See [Manage your API keys](/docs/authorization/api-keys).

## ✨ Entity hooks can change the entity they're gating

An [entity hook](/docs/entity-hooks/) used to answer one question: does this operation go ahead or not. Now it can also hand data back. Add a `callback_body` object to the `PATCH` you send to the hook's `callback_url`, and nullplatform merges those fields into the entity when it resumes the operation.

```json title="PATCH callback-url"
{
  "status": "success",
  "callback_body": {
    "repository_url": "https://github.com/my-org/my-service"
  }
}
```

For example, a before-hook on `application:create` can pick the repository the application lives in by your own rules, instead of whatever the developer typed. `callback_body` accepts any field the entity's update endpoint accepts.

👉 See [Updating the entity from the hook](/docs/entity-hooks/setup#updating-the-entity-from-the-hook). The [Entity hook API](/docs/entity-hook-api-index) is also in the reference now.

## ✨ Packages: pin a specification and its artifacts

A **package** is a versioned bundle of what makes a service work. Each revision carries an immutable bill of materials that pins service, action and link specifications together with the [artifacts](/docs/artifact-api-index) behind them, so changing a specification later never changes what a published revision pins. A service binds to its package's default revision when you create it, and `desired_package_revision_id` moves it to another one.

👉 See [Service and link specifications API](/docs/service-specification-api-index), which walks through packaging a specification step by step, and the [Packages](/docs/package-api-index) reference.

## ✨ Push to ECR without long-lived AWS keys

`np asset push` takes its registry credentials from the asset repository provider configured in nullplatform, which for ECR meant storing an access key and a secret key. You can now store an **IAM role** instead, and [CLI 2.11.0](#cli-2110) assumes it at push time with your CI tool's OpenID Connect (OIDC) token. No long-lived AWS credentials, not in the pipeline and not in nullplatform.

Set it in **Platform settings > Asset repository**, on your ECR configuration, under **CI/CD Image Push Configuration**:

<img alt="The ECR asset repository configuration with the new Role ARN field under CI/CD Image Push Configuration" src="/img/providers/ecr-ci-push-role-arn.png" width="90%" className="helper-image" />

On GitHub Actions, the job only needs the `id-token: write` permission:

```yaml
permissions:
  id-token: write
  contents: read
```

GitLab CI, Bitbucket Pipelines and CircleCI work too, with a few more lines. Once a role is configured, the provider's keys are ignored, so you can add the role, confirm your pipelines still push, and then remove the keys.

👉 See [Asset push authentication](/docs/applications/ci-cd/asset-push-authentication) for the setup per CI tool and the IAM permissions the role needs.

## ✨ CLI, agent, and scopes releases

### CLI 2.11.0

The CLI shipped **2.11.0**: `np asset push` can assume the IAM role on your ECR provider, `np mcp serve` adds an `np_request` tool for API paths the entity tools don't cover, and `np service workflow build-context` exposes every provider of a category by its specification slug.

👉 See the [CLI 2.11.0 release notes](/changelog/cli-2.11.0).

### Agent 0.12.0 and 0.13.0

The [control plane agent](/docs/agent/overview) shipped two releases:

- **Security update.** 0.12.0 is built with Go 1.26.8 and updated `grpc` and `x/crypto` modules, clearing known vulnerabilities.
- **CLI 2.11.0 in the image.** 0.13.0 ships the latest nullplatform CLI.
- **`plaintext` names the no-TLS worker mode.** Set `NP_WORKER_SECURITY=plaintext`. `insecure` still works as a deprecated alias and logs a warning.

👉 See every [agent release](/changelog/tags/agent).

### Scopes 1.17.0 and 1.18.0

The [scopes](/docs/agent-backed-scopes/) repository shipped two releases:

- **Readable Kubernetes object names.** Containers scopes can name their objects from the application and scope slugs, so a Deployment reads `checkout-api-staging-789012` instead of `d-123456-789012`, or from a pattern you write. Existing scopes keep their names. See [Resource naming](/docs/agent-backed-scopes/containers/resource-naming).
- **Run once for scheduled tasks.** A [scheduled task](/docs/agent-backed-scopes/scheduled-tasks) scope can run a single time when it's deployed, instead of on a recurring schedule.
- **Turning the health check off removes the probes.** Until now the setting was accepted and the probes stayed, so an application that was slow to answer kept being restarted.

And more: a Kubernetes scope can use a custom domain and additional ports together, rollbacks explain why the deployment failed, and Route53 scopes keep their ALB on every deployment. 👉 See every [scopes release](/changelog/tags/scopes).

## ✨ Sign in from the docs and the website

The docs navbar and the header of [nullplatform.com](https://www.nullplatform.com/) now have a **Sign in** button. Both take you to **Sign in to your workspace**, where you enter your organization's URL and continue to nullplatform.

After your first sign-in, the page remembers your workspace. Next time, pick it from **Your recent workspaces** instead of typing the URL again.

<SignInScene />

## Also in September

- **A failed checklist run has three outcomes, not two.** The approval action's `on_checklist_fail` decides whether the request is denied, stays pending, or goes to manual review right away. See [Choose what a failed run does](/docs/approvals/checklist-specs#choose-what-a-failed-run-does).
- **Deleting an application is a status change, not a `DELETE`.** Patch the application's status to `deleting` from the UI, `np application patch`, or the API. See [Delete applications](/docs/applications/delete-application).
- **A map for the service and specification APIs.** Two new index pages list every entity with its endpoints and what it nests under: [Service and link specifications API](/docs/service-specification-api-index) and [Service and link API](/docs/services-api-index).

---

That's all for September, from the **nullplatform** team! ❤️
