1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//! # corteq-onepassword
//!
//! Secure 1Password SDK wrapper for Rust applications.
//!
//! This crate provides a safe, ergonomic interface to 1Password secrets
//! using FFI bindings to the official 1Password SDK Core library.
//!
//! ## Features
//!
//! - **Secure by default** - Secrets are wrapped in [`SecretString`] with automatic
//! memory zeroization
//! - **Simple API** - Retrieve secrets with a single function call
//! - **Thread-safe** - Client is `Send + Sync` for use in async applications
//! - **Builder pattern** - Flexible configuration with sensible defaults
//!
//! ## Quick Start
//!
//! ```no_run
//! use corteq_onepassword::{OnePassword, ExposeSecret};
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! // Create client from OP_SERVICE_ACCOUNT_TOKEN environment variable
//! let client = OnePassword::from_env()?
//! .integration("my-app", "1.0.0")
//! .connect()
//! .await?;
//!
//! // Resolve a secret
//! let api_key = client.secret("op://vault/item/api-key").await?;
//!
//! // Use the secret (expose only when needed)
//! println!("API key length: {}", api_key.expose_secret().len());
//!
//! Ok(())
//! }
//! ```
//!
//! ## Authentication
//!
//! This crate uses 1Password service account tokens for authentication.
//! Personal account tokens are not supported.
//!
//! ### Environment Variable (Recommended)
//!
//! Set the `OP_SERVICE_ACCOUNT_TOKEN` environment variable:
//!
//! ```bash
//! export OP_SERVICE_ACCOUNT_TOKEN="ops_..."
//! ```
//!
//! Then use [`OnePassword::from_env()`]:
//!
//! ```no_run
//! use corteq_onepassword::OnePassword;
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let client = OnePassword::from_env()?.connect().await?;
//! Ok(())
//! }
//! ```
//!
//! ### Explicit Token
//!
//! For testing or special deployments, use [`OnePassword::from_token()`]:
//!
//! ```no_run
//! use corteq_onepassword::OnePassword;
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let token = std::env::var("MY_TOKEN")?;
//! let client = OnePassword::from_token(&token)?
//! .connect()
//! .await?;
//! Ok(())
//! }
//! ```
//!
//! ## Secret References
//!
//! Secrets are referenced using the `op://vault/item/field` format:
//!
//! - `op://Production/Database/password` - Simple reference
//! - `op://Production/Database/admin/password` - Section-scoped reference
//!
//! ## Batch Operations
//!
//! Resolve multiple secrets efficiently:
//!
//! ```no_run
//! use corteq_onepassword::{OnePassword, ExposeSecret};
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let client = OnePassword::from_env()?.connect().await?;
//!
//! // Batch resolution (returns Vec)
//! let secrets = client.secrets(&[
//! "op://prod/db/host",
//! "op://prod/db/user",
//! "op://prod/db/pass",
//! ]).await?;
//!
//! // Named resolution (returns SecretMap)
//! let secrets = client.secrets_named(&[
//! ("host", "op://prod/db/host"),
//! ("user", "op://prod/db/user"),
//! ("pass", "op://prod/db/pass"),
//! ]).await?;
//!
//! let host = secrets.get("host").expect("host secret").expose_secret();
//! Ok(())
//! }
//! ```
//!
//! ## Sharing the Client
//!
//! The client is thread-safe and can be shared via `Arc`:
//!
//! ```no_run
//! use std::sync::Arc;
//! use corteq_onepassword::OnePassword;
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let client = Arc::new(OnePassword::from_env()?.connect().await?);
//!
//! let client1 = Arc::clone(&client);
//! let client2 = Arc::clone(&client);
//!
//! tokio::join!(
//! async move { client1.secret("op://vault/item/field1").await },
//! async move { client2.secret("op://vault/item/field2").await },
//! );
//! Ok(())
//! }
//! ```
//!
//! ## Feature Flags
//!
//! - `blocking` - Enable synchronous API via [`OnePasswordBuilder::connect_blocking()`]
//! - `tracing` - Enable tracing spans for observability
//!
//! ## Security
//!
//! This crate is designed with security as a primary concern:
//!
//! - **Tokens** are wrapped in [`SecretString`] and zeroized on drop
//! - **Secrets** are never logged or included in error messages
//! - **Debug** implementations redact sensitive data
//! - **Native library** is verified via SHA256 checksum at build time
//!
//! ## Platform Support
//!
//! | Platform | Architecture | Status |
//! |----------|--------------|--------|
//! | Linux | x86_64 | ✅ Supported |
//! | Linux | aarch64 | ✅ Supported |
//! | macOS | x86_64 | ✅ Supported |
//! | macOS | aarch64 | ✅ Supported |
//! | Windows | - | ❌ Not supported |
//! | Alpine | - | ❌ Not supported (musl) |
// Public API
pub use ;
pub use ;
pub use ;
// Re-export secrecy types for user convenience
// This allows users to import everything they need from this crate
pub use ;