Skip to content

RFC 103 - std.secrets secret strings and bytes #661

@dannymeijer

Description

@dannymeijer

Area

  • Runtime / Core crates (stdlib/core/derive)
  • Tooling (CLI/formatter/test runner)
  • Documentation

Summary

RFC 103 proposes std.secrets as the standard library home for SecretStr and SecretBytes: typed secret values that preserve redaction across display, debug output, diagnostics, structured logs, telemetry, semantic inspection, generated reports, default serialization, HTTP auth helpers, CLI inputs, environment access, and typed workflow actions.

Motivation

Secrets should not accidentally become plaintext just because they flow through normal program surfaces. Tokens, private keys, passwords, SAML assertions, client secrets, and similar credentials often start in environment or CLI configuration, pass through typed config, enter HTTP or cryptographic helpers, and appear near logs, telemetry, errors, reports, or action metadata. Python-style wrappers and per-logger filters help, but they are easy to bypass because each boundary has to cooperate separately.

Incan can make the safer path the default by attaching secrecy to the value type and making plaintext exposure scoped, explicit, and visible to tooling.

Proposal sketch

Add std.secrets with concrete SecretStr and SecretBytes types.

Key constraints:

  • Plaintext exposure is deny-by-default for Incan-owned display, debug, panic formatting, assertion messages, diagnostics, structured logs, telemetry, semantic inspection, generated reports, CLI echo, default serialization, and action metadata.
  • Raw access should use intentionally named scoped reveal operations, or trusted stdlib APIs that accept secret values and own the reveal internally.
  • SecretBytes and SecretStr should support protected idle storage where the backend can meaningfully provide it, with zeroization of plaintext reveal buffers where supported.
  • The contract should be honest about limits: encrypted idle memory does not protect against arbitrary code execution inside the same process, debuggers with full process access, crash dumps, or backend APIs that must receive plaintext.
  • Higher-level identity protocols such as SAML, OAuth, OIDC, JWT validation, service-account exchange, and SSO should consume secret values, but remain outside std.secrets.

Draft RFC: workspaces/docs-site/docs/RFCs/103_secret_values.md.

Alternatives considered

  • Plain newtype str / newtype bytes: insufficient because secrecy changes display, debug, serialization, logging, telemetry, equality, copying, reveal, and memory behavior.
  • Logging-only redaction: too late because secrets leak through more than logs.
  • HTTP-only secret headers: too narrow because secrets originate in config, CLI, environment, secret providers, and typed actions.
  • One generic Secret[T] first: likely useful later, but strings and bytes need distinct encoding, reveal, comparison, and storage contracts.
  • Unscoped raw getters: too easy to store, log, serialize, or return plaintext accidentally.

Impact / compatibility

This is additive. Existing code that uses plain strings or bytes for credentials remains valid, but new stdlib docs and examples should prefer SecretStr and SecretBytes at environment, CLI, ctx, HTTP, telemetry, logging, and workflow-action boundaries.

The feature affects stdlib/runtime behavior, generated Rust display/debug implementations, typechecking for implicit conversion to plain str/bytes, LSP/tooling visibility for reveal sites, and docs/examples.

Implementation notes (optional)

Likely layers:

  • std.secrets runtime types and helpers.
  • Typechecker rejection of implicit downcasts from secret wrappers to plain strings or bytes.
  • Generated Rust redacting display/debug behavior.
  • Protected idle storage and zeroization where target support allows it.
  • Integration hooks for std.environ, ctx, typed CLI, std.http, std.logging, std.telemetry, typed actions, and semantic inspection.

Testing should cover formatting, debug output, structured serialization, nested containers, error paths, HTTP diagnostics, telemetry/logging output, reveal-site behavior, and backend memory-handling guarantees where supported.

Checklist

  • I checked for an existing RFC/issue covering this.
  • I can describe how this impacts existing code and how to migrate (if needed).

Metadata

Metadata

Assignees

No one assigned

    Labels

    RFCAdding or updating RFC documentsdocumentationImprovements or additions to documentationruntime / core cratesSuggestions, features, or bugs related to the `incan-core`, `incan-stdlib`, 'incan-derive` cratestoolingSuggestions, features, or bugs related to the Tooling (CLI/formatter/test runner)

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions