tsafe-gcp 1.2.0

GCP Secret Manager HTTP client for tsafe — pull/push secrets from Google Cloud to the local encrypted vault
Documentation
# tsafe-gcp

GCP Secret Manager integration for [tsafe](https://crates.io/crates/tsafe-cli).

## What this does

Synchronous HTTP client for pulling secrets from GCP Secret Manager into the
local tsafe vault, with explicit push helpers for operator-approved write-back.
The local vault remains the default working source of truth; no secret data is
written back to GCP unless a `tsafe gcp-push` workflow is invoked.

Used by the gated `tsafe gcp-pull` and `tsafe gcp-push` command surfaces.

## Direct use

Most users should install the CLI:

```
cargo install tsafe-cli
```

This crate is published separately for consumers who want to call the GCP
Secret Manager REST API from Rust without pulling in the full CLI surface.

```toml
[dependencies]
tsafe-gcp = "1"
```

## Auth

Authentication is resolved in this order:

1. **`GOOGLE_OAUTH_TOKEN`** — a pre-obtained OAuth2 bearer token (e.g. from
   `gcloud auth print-access-token`). Useful in CI.
2. **GCE metadata server** — tried automatically when running on GCE, Cloud
   Run, or GKE with a service account attached.
3. **Application Default Credentials file** — path from
   `GOOGLE_APPLICATION_CREDENTIALS`, or the well-known location
   `~/.config/gcloud/application_default_credentials.json`.

The project ID is resolved from `GOOGLE_CLOUD_PROJECT`, then `GCLOUD_PROJECT`,
then the GCE metadata server.

| Variable                         | Required | Description                                          |
|----------------------------------|----------|------------------------------------------------------|
| `GOOGLE_CLOUD_PROJECT`           | yes*     | GCP project ID                                       |
| `GCLOUD_PROJECT`                 | yes*     | Alternate project ID env var                         |
| `GOOGLE_OAUTH_TOKEN`             | auth†    | Pre-obtained OAuth2 token                            |
| `GOOGLE_APPLICATION_CREDENTIALS` | auth†    | Path to ADC JSON file                                |

\* Falls back to the GCE metadata server when neither env var is set.
† Authentication tries `GOOGLE_OAUTH_TOKEN` first, then GCE metadata, then ADC.

## Key normalisation

Secret names such as `my-db-password` are normalised to `MY_DB_PASSWORD`
(hyphens and dots replaced with underscores, uppercased) so they are
immediately usable as environment variable names.

## Example

```rust
use tsafe_gcp::{GcpConfig, acquire_token, pull_secrets};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let cfg = GcpConfig::from_env()?;
    // acquire_token tries GOOGLE_OAUTH_TOKEN, then GCE metadata, then ADC.
    let secrets = pull_secrets(&cfg, &|| acquire_token(&cfg), None)?;
    for (key, value) in &secrets {
        println!("{key}=<{} bytes>", value.len());
    }
    Ok(())
}
```

To pull only secrets whose names begin with a given prefix:

```rust
let secrets = pull_secrets(&cfg, &|| acquire_token(&cfg), Some("app-"))?;
```

The prefix filter is applied client-side after listing; the list call uses
`pageSize=100` and follows `nextPageToken` for pagination automatically.

## Secret payload encoding

GCP Secret Manager returns secret payloads as standard base64. The client
decodes them and returns plain UTF-8 strings. Binary secrets (non-UTF-8
payloads) are not supported and will return an error.

## Retry behaviour

The HTTP client retries on 429 (throttled) responses, honouring the
`Retry-After` header when present, and retries on transient transport errors
with exponential backoff and jitter. Both retry budgets are capped at 30
seconds per attempt.

## License

Same as the tsafe workspace — see the repository root.