---
title: Explanation
description: Why rtb-credentials is shaped the way it is — the precedence order, the secret type, the CI refusal, the Linux default, and what it deliberately does not do.
tags:
- explanation
---
# Explanation
Background and reasoning. These pages answer "why is it like this",
where the [reference](../reference/index.md) answers "what does it do"
and the [how-to guides](../how-to/index.md) answer "how do I".
| [Why the precedence chain is ordered this way](precedence-chain.md) | Why `env` beats the keychain, why there are two environment legs, and why the order cannot be configured. |
| [Why every secret is a `SecretString`](secret-handling.md) | What the type prevents that a `String` does not, and why it can be deserialised but not serialised. |
| [Why literal secrets are refused in CI](refusing-literals-in-ci.md) | What the refusal protects against, and why detection is one exact string. |
| [Why Linux keychain storage is session-scoped by default](linux-keychain-persistence.md) | The build-hermeticity trade behind kernel keyutils, and what `linux-persistent` really buys. |
| [What this crate does not do](limitations.md) | Deliberate omissions, unsupported combinations, and known rough edges. |
## Where this crate sits
`rtb-credentials` is one crate in the
[phpboyscout Rust toolkit](https://rust.phpboyscout.uk), extracted from
the [rust-tool-base](https://gitlab.com/phpboyscout/rust-tool-base)
framework so it can be used without adopting the framework around it. It
depends on no other toolkit crate.
Its scope is narrow on purpose: retrieve a stored static secret, and
keep it in a type that resists leaking. Deciding *which* credential a
tool needs is the tool's job; storing one durably is the platform's job;
refreshing a short-lived token is outside the model entirely.
A sibling component in the Go toolkit,
[`go/credentials`](https://gitlab.com/phpboyscout/go/credentials),
solves the same problem for Go tools with the same three storage modes
and the same precedence. The designs are intentionally parallel, but
they are separate implementations and the Rust one differs where Rust
allows something Go cannot — most visibly in
[secret handling](secret-handling.md).