Platform

Platform overviewArchitectureWorkflow orchestrationGitOps configurationGovernance and AAAAI and MCPKnowledge and contextRuntime and executionEvidence and monitoring

Use cases

All use casesProduction incidentRelease preparationHotfix to productionSecurity scan triage
Why NopsAIIntegrationsSecurity

Resources

All resourcesAI agent governanceMCP governanceMCP securitySelf-hosted platforms
PricingGitHub

Company

How a run worksAboutContactBook a demo

Secrets in steps

Declaring the credentials a step needs, and what the platform does with them.

ReferenceAutomation authorSecurity

Key points

  • Secrets are declared per step, not per pipeline, so a credential is not injected into steps that have no use for it.
  • A declared secret is injected as an environment variable under its bare name.
  • Cross-scope references work exactly as they do for variables: scope/path:NAME.
  • Declared secret values are masked in run logs.
  • A stored secret value can be read back through GET /v1/secrets/{name}, but only by a caller holding secret.read_value on that secret. Treat that action as the sensitive one.
  • The same runtime name may not resolve from two different scopes in one step.

Examples

What this page addsyaml
    secrets:
      - REGISTRY_TOKEN
      - platform/shared:SIGNING_KEY
Pipeline so faryaml
name: release-service
description: Build, verify, and publish the payments service.
container_image: alpine:3.20
working_directory: /workspace
timeout: 45m
variables:
  - RELEASE_CHANNEL
  - platform/shared:ARTIFACT_BUCKET
steps:
  - name: build
    script: |
      make build
      echo "1.0.$(date +%s)" > /nopsai/outputs/BUILD_TAG
    outputs:
      - name: BUILD_TAG

  - name: verify
    image: golang:1.24
    depends_on: [build]
    runtime_pool: ci
    volumes:
      - build-cache:/root/.cache
    script: |
      go vet ./...
      go test ./...

  - name: checks
    depends_on: [verify]
    tasks:
      - name: licenses
        script: |
          ./scripts/license-check.sh
      - name: sbom
        script: |
          ./scripts/sbom.sh > /workspace/sbom.json
          sha256sum /workspace/sbom.json | cut -d' ' -f1 > /nopsai/outputs/SBOM_DIGEST
        outputs:
          - name: SBOM_DIGEST
      - name: report
        depends_on: [checks.licenses, checks.sbom]
        variables:
          SBOM_DIGEST: $steps.checks.sbom.outputs.SBOM_DIGEST
        script: |
          echo "checks complete"
          echo "sbom $SBOM_DIGEST"

  - name: package
    depends_on: [checks]
    secrets:
      - REGISTRY_TOKEN
      - platform/shared:SIGNING_KEY
    variables:
      BUILD_TAG: $steps.build.outputs.BUILD_TAG
    script: |
      ./scripts/package.sh "$BUILD_TAG"
      echo "channel $RELEASE_CHANNEL, bucket $ARTIFACT_BUCKET"
      ./scripts/mint-token.sh > /nopsai/outputs/PUBLISH_TOKEN
      ./scripts/sign.sh --key "$SIGNING_KEY" --token "$REGISTRY_TOKEN"
    outputs:
      - name: PUBLISH_TOKEN
        sensitive: true
Result

package can sign and publish; the two values appear masked wherever the run logs are rendered.

Rejected: a secret name with an unsupported characteryaml
    secrets:
      - registry/token
Result

Rejected: names must match ^[A-Za-z0-9_.-]+$, and a / is read as a scope separator.

Field reference

steps[].secretsstepstring[]OptionalNone

Scoped secret references injected into the step as environment variables.

Example

secrets:
  - REGISTRY_TOKEN
  - platform/shared:SIGNING_KEY

Rules
  • Names must match ^[A-Za-z0-9_.-]+$.
  • The same runtime name may not resolve from two different scopes in one step.
Security

Declared secret values are masked in run logs.

Evidence

services/nopsai/pkg/validation/pipeline.go

How it works

Declaring a secret is an access statement. It is visible in review, it is auditable, and it is the thing a security reviewer reads to answer "what can this step reach?".

For a secret that should live in Git rather than the database, encrypt it first through POST /v1/secrets/encrypt; the envelope is safe to commit and resolves at run time.

Masking covers declared secrets and outputs marked sensitive. A value the pipeline constructs itself — a token pasted into a log line by a script — is not something the platform can know about.

Implementation evidence

  • pkg/models/runtime_refs.go

    Scoped secret reference parsing.

  • doc/credential-management.md

    Encrypted registry, GitOps envelopes, rotation, and AAA.