# Credential lifecycle
> **TARGET architecture — implementation pending.** This is the authoritative
> contract for credential construction, storage, transport trust, and rotation.
## Required simple secrets
A simple required provider secret enters as a required builder argument:
```rust,ignore
let captcha = Turnstile::builder(secret)
.build()?;
```
The signature accepts `secret: impl Into<String>`. The builder immediately moves
it into private, redacted, non-serializable
credential storage and validates it at build. There is no universal public
secret wrapper, no public secret getter, and no optional `.credentials(...)` setter
for mandatory authentication. Provider-appropriate bytes or strings are also
appropriate for simple ALTCHA/HMAC construction.
The private credential container implements neither `Clone`, `Display`,
`Serialize`, nor `Deserialize`; its `Debug` is redacted. `Captcha` clones share
the same private container through `Arc<CaptchaInner>`, so cloning the handle
does not duplicate credential bytes. The implementation performs best-effort
zeroization when the final owner drops, without claiming to erase prior copies
held in caller `String` values, environment variables, allocator history, or
operating-system memory.
## Structured authentication
A public credential type is justified only when authentication is genuinely
structured. reCAPTCHA Enterprise is the primary example:
```rust,ignore
let credentials = EnterpriseCredentials::api_key(api_key)?;
// Or an illustrative service-account/token-provider construction:
let credentials = EnterpriseCredentials::service_account(service_account)?;
let captcha = providers::recaptcha::enterprise::Recaptcha::builder(credentials)
.project_id(project_id)
.site_key(site_key)
.build()?;
```
`recaptcha::enterprise::EnterpriseCredentials` has private fields and redacted
`Debug`, and implements neither serialization nor deserialization. The exact
service-account/token-provider abstraction remains an implementation detail;
the public type models real authentication alternatives without exposing secret
getters.
## Privileged transport boundary
Provider adapters must serialize credentials to send verification requests.
The secure default transport handles those bytes without logging them. An
injected custom [`HttpTransport`](http-transport.md), however, necessarily sees
serialized credentials and token bytes and is fully trusted. The SDK cannot
prevent a malicious custom transport from retaining or logging them.
## Initial rotation model
Initial rotation constructs a new `Captcha` with the replacement credential and
atomically replaces the application-level shared handle. In-flight clones finish
with the old immutable configuration; new work uses the new handle. Applications
must account for provider cutover order, old-credential revocation timing, retry
windows, and how long in-flight work can retain the old `Arc`.
The initial target has no hot credential mutation, credential lock, or public
`CredentialProvider`. Optional credential-source integrations are later work.
This keeps ordinary reads lock-free and makes credential lifetime follow the
configured handle explicitly.