Skip to content

Commit 4b3e9b9

Browse files
committed
docs: rework landing page
1 parent 7a55ec6 commit 4b3e9b9

File tree

1 file changed

+119
-71
lines changed

1 file changed

+119
-71
lines changed

docs/src/content/docs/index.mdx

Lines changed: 119 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
---
22
title: SecretSpec
3-
description: Declarative secrets for development workflows, supporting a variety of storage backends.
3+
description: Declarative secrets for development workflows, supporting a variety of provisioning backends.
44
template: splash
55
hero:
6-
tagline: Declarative secrets for development workflows, supporting a variety of storage backends.
6+
tagline: Declarative secrets for development workflows, supporting a variety of provisioning backends.
77
image:
88
file: ../../assets/logo.png
99
actions:
@@ -18,7 +18,7 @@ hero:
1818

1919
import { Card, CardGrid, LinkCard, Aside } from '@astrojs/starlight/components';
2020

21-
## The Problem
21+
## Why Secrets Are Still Hard
2222

2323
Current secret management forces applications to answer three questions at once:
2424

@@ -28,66 +28,11 @@ Current secret management forces applications to answer three questions at once:
2828

2929
This coupling creates vendor lock-in, runtime failures, poor developer experience, and inconsistent practices.
3030

31-
## The Solution
32-
33-
SecretSpec separates these concerns:
34-
35-
<CardGrid>
36-
<LinkCard
37-
title="WHAT secrets are needed"
38-
href="/reference/configuration/"
39-
description="Declared in secretspec.toml"
40-
/>
41-
<LinkCard
42-
title="HOW requirements vary"
43-
href="/concepts/profiles/"
44-
description="Managed through profiles"
45-
/>
46-
<LinkCard
47-
title="WHERE secrets are stored"
48-
href="/reference/providers/"
49-
description="Configured via providers"
50-
/>
51-
</CardGrid>
31+
## WHAT - Declaring Your Secrets
5232

53-
This separation enables portable applications, early validation, better tooling, and type safety.
33+
Applications declare their secret requirements in a `secretspec.toml` file.
5434

55-
## Features
56-
57-
<CardGrid>
58-
<LinkCard
59-
title="Configuration Inheritance"
60-
href="/concepts/inheritance/"
61-
description="Share common secrets across projects using extends"
62-
/>
63-
<LinkCard
64-
title="Type-Safe Rust SDK"
65-
href="/sdk/rust/"
66-
description="Generate strongly-typed structs from your configuration"
67-
/>
68-
<LinkCard
69-
title="Smart Discovery"
70-
href="/quick-start/"
71-
description="Import existing secrets from .env files automatically"
72-
/>
73-
<LinkCard
74-
title="CLI Tools"
75-
href="/reference/cli/"
76-
description="Check, set, and run commands with secrets injected"
77-
/>
78-
<LinkCard
79-
title="Multiple Providers"
80-
href="/reference/providers/"
81-
description="Support for Keyring, dotenv, 1Password, LastPass, and more"
82-
/>
83-
<LinkCard
84-
title="Early Validation"
85-
href="/concepts/overview/"
86-
description="Catch missing secrets before your application starts"
87-
/>
88-
</CardGrid>
89-
90-
## Quick Example
35+
Each secret is defined with its name and description, creating a single source of truth that's version controlled alongside your code. This standardized format enables ecosystem-wide tooling and ensures every developer knows exactly what secrets the application needs.
9136

9237
```toml
9338
[project]
@@ -96,26 +41,129 @@ revision = "1.0"
9641

9742
[profiles.default]
9843
DATABASE_URL = { description = "PostgreSQL connection string", required = true }
99-
REDIS_URL = { description = "Redis connection string", required = false, default = "redis://localhost:6379" }
44+
REDIS_URL = { description = "Redis connection string", required = false }
45+
```
10046

101-
[profiles.production]
102-
DATABASE_URL = { description = "PostgreSQL connection string", required = true }
103-
REDIS_URL = { description = "Redis connection string", required = true }
47+
```bash
48+
# Initialize secretspec.toml from existing .env files
49+
$ secretspec init --from .env
10450
```
10551

106-
## Get Started in Minutes
52+
[Learn more about declarative configuration →](/concepts/declarative/)
53+
54+
## HOW - Managing Requirements with Profiles
55+
56+
SecretSpec's profile system allows you to specify different requirements, defaults, and validation rules for development, staging, production, or any custom environment.
57+
58+
A secret might be optional with a local default in development but required in production - all without changing your application code.
59+
60+
```toml
61+
[project]
62+
name = "my-app"
63+
revision = "1.0"
64+
65+
[profiles.default]
66+
DATABASE_URL = { description = "PostgreSQL connection string", required = true }
67+
REDIS_URL = { description = "Redis connection string", required = false }
68+
69+
[profiles.development]
70+
# Override with development-friendly defaults
71+
DATABASE_URL = { default = "postgresql://localhost/myapp_dev" }
72+
REDIS_URL = { default = "redis://localhost:6379" }
73+
```
10774

10875
```bash
109-
# Initialize from existing .env file
110-
$ secretspec init --from .env
76+
# Run with a specific profile
77+
$ secretspec run --profile development -- npm start
78+
$ secretspec run --profile production -- npm start
79+
80+
# Or use environment variables
81+
$ SECRETSPEC_PROFILE=development secretspec run -- npm start
82+
$ SECRETSPEC_PROFILE=production secretspec run -- npm start
83+
```
84+
85+
[Learn more about profiles →](/concepts/profiles/)
86+
87+
## WHERE - Flexible provisioning with Providers
11188

112-
# Set up your preferred provider
89+
The same application works across different secret storage backends without any code changes.
90+
91+
```bash
92+
# Configure your default provider interactively
11393
$ secretspec config init
94+
? Select your preferred provider backend:
95+
> keyring: Uses system keychain (Recommended)
96+
1password: 1Password password manager
97+
dotenv: Traditional .env files
98+
env: Read-only environment variables
99+
lastpass: LastPass password manager
100+
? Select your default profile:
101+
> development
102+
default
103+
none
104+
✓ Configuration saved to ~/.config/secretspec/config.toml
105+
```
106+
107+
**Supported providers:**
108+
- [**Keyring**](/providers/keyring/) - System credential store (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux)
109+
- [**Dotenv**](/providers/dotenv/) - Traditional .env files for local development
110+
- [**Environment**](/providers/env/) - Read-only access to environment variables for CI/CD
111+
- [**1Password**](/providers/1password/) - Team-based password management
112+
- [**LastPass**](/providers/lastpass/) - Cloud-based password manager
113+
114+
```bash
115+
# Check all secrets are available and set them if not
116+
$ secretspec check
117+
$ secretspec set DATABASE_URL
118+
119+
# Override provider for specific commands
120+
$ secretspec run --provider env -- npm test
121+
$ secretspec run --provider 1password://vault -- npm start
122+
123+
# Or use environment variables
124+
$ SECRETSPEC_PROVIDER=env secretspec run -- npm test
125+
$ SECRETSPEC_PROVIDER=1password://vault secretspec run -- npm start
126+
```
127+
128+
[Learn more about providers →](/concepts/providers/)
129+
130+
This separation enables portable applications, early validation, better tooling, and type safety.
131+
132+
## Type-Safe Rust SDK
133+
134+
While the CLI is great for development workflows, integrating SecretSpec directly into your application provides better type safety and error handling.
135+
136+
The Rust SDK generates strongly-typed structs from your `secretspec.toml`, ensuring compile-time verification of your secret access.
137+
138+
```rust
139+
// Generate typed structs from secretspec.toml
140+
secretspec::define_secrets!("secretspec.toml");
141+
142+
fn main() -> Result<(), Box<dyn std::error::Error>> {
143+
// Load secrets with type-safe struct
144+
let secretspec = SecretSpec::load(Some(Provider::Keyring), Some(Profile::Production))?;
114145

115-
# Run your application with secrets
116-
$ secretspec run -- npm start
146+
// Field names are lowercased versions of secret names
147+
if let Some(database_url) = &secretspec.secrets.database_url {
148+
println!("Database: {}", database_url); // DATABASE_URL -> database_url
149+
}
150+
151+
// Optional secrets are Option<String>
152+
if let Some(redis_url) = &secretspec.secrets.redis_url {
153+
println!("Redis: {}", redis_url);
154+
}
155+
156+
// Set all secrets as environment variables
157+
secretspec.secrets.set_as_env_vars();
158+
159+
Ok(())
160+
}
117161
```
118162

163+
[Learn more about the Rust SDK →](/sdk/rust/)
164+
165+
*SDKs for other languages are welcome! Please see our [contribution guide](https://github.com/cachix/secretspec) if you'd like to help.*
166+
119167
---
120168

121169
*SecretSpec was designed by [Cachix](https://cachix.org) for [devenv.sh](https://devenv.sh). See the [announcement post](https://devenv.sh/blog/2025/01/08/secretspec).*

0 commit comments

Comments
 (0)