> ## Documentation Index
> Fetch the complete documentation index at: https://docs.knoxcall.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Creating Your First Secret

> Store API keys and credentials securely with encrypted secrets. Learn how to inject secrets into requests server-side.

# Creating Your First Secret

Learn how to store sensitive credentials securely and inject them into backend requests without exposing them to clients.

## What is a Secret?

A **secret** in KnoxCall is an **encrypted credential** (API key, password, token) that's injected into your backend requests **server-side**. Your clients never see the actual value.

### Why Use Secrets?

**Without KnoxCall secrets:**

```javascript theme={"dark"}
// ❌ Frontend code - API key exposed in browser!
fetch("https://api.stripe.com/charges", {
  headers: {
    "Authorization": "Bearer sk_live_abc123xyz789..."
  }
});
```

Anyone with dev tools can see your Stripe key! 😱

**With KnoxCall secrets:**

```javascript theme={"dark"}
// ✅ Frontend code - No secrets exposed
fetch("https://a1b2c3d4.DunderMifflin.knoxcall.com/api/payments", {
  headers: {
    "x-knoxcall-key": "tk_abc123...",
    "x-knoxcall-route": "stripe-payments"
  }
});
```

KnoxCall injects your Stripe key server-side:

```text theme={"dark"}
Client Request → KnoxCall → Adds "Authorization: Bearer sk_live_abc..." → Stripe API
```

Your secret stays secure on KnoxCall's servers! 🔐

## Secret Types

KnoxCall supports three types of secrets:

### 1. API Key / String (Most Common)

Simple encrypted values:

* API keys (Stripe, SendGrid, Twilio)
* Passwords (database, services)
* Tokens (auth tokens, webhook secrets)
* Any sensitive string value

### 2. OAuth2 (Advanced)

Full OAuth2 flow with automatic token refresh:

* Google OAuth tokens (auto-refreshes when expired)
* Shopify, HubSpot, Microsoft, Slack OAuth
* Stores access token, refresh token, and expiry
* Handles token rotation automatically

### 3. Certificate

SSL/TLS certificates and private keys:

* SSL/TLS certificates for mutual TLS (mTLS) authentication
* Private keys for signing and encryption
* Client certificates for API authentication

We'll focus on **string secrets** in this guide.

## How Secrets Work

```text theme={"dark"}
1. You create secret in KnoxCall UI
     ↓
2. Value encrypted with AES-256-GCM
     ↓
3. Stored securely in encrypted vault
     ↓
4. You reference secret in route config: {{secret:stripe_key}}
     ↓
5. Client makes request through KnoxCall
     ↓
6. KnoxCall decrypts secret server-side
     ↓
7. Injects decrypted value into backend request
     ↓
8. Backend receives request with actual API key
     ↓
9. Client never sees the secret value!
```

**Encryption:** AES-256-GCM with envelope encryption (same security as AWS, Google Cloud)

## Create Your First Secret

### Step 1: Navigate to Secrets

1. Open the **Protect** section in the sidebar
2. Select **Secrets**
3. Click **Add Secret**

### Step 2: Choose Secret Type

Select **String Secret** (for this guide)

### Step 3: Fill in Details

**Secret Name:**

```text theme={"dark"}
stripe_prod_key
```

*Lowercase with underscores. This is how you'll reference it in templates.*

**Secret Value:**

```text theme={"dark"}
sk_live_abc123xyz789def456ghi789jkl012
```

*Paste your actual Stripe API key*

### Step 4: Save

Click **Create Secret**

The value is immediately encrypted using AES-256-GCM. You'll never see the plaintext value again in the UI!

<Warning>
  **Copy your secret value elsewhere if you need it!** Once saved, KnoxCall only shows encrypted form. The plaintext cannot be retrieved (only used in requests).
</Warning>

## Use Secret in a Route

Now let's inject your secret into backend requests.

### Step 1: Edit Your Route

1. Navigate to **Routes**
2. Click your route (e.g., "stripe-payments")
3. Click **Edit**

### Step 2: Inject Secret in Headers

Find the **Inject Headers** section and add:

```json theme={"dark"}
{
  "Authorization": "Bearer {{secret:stripe_prod_key}}"
}
```

**Template syntax:** `{{secret:name}}`

* `secret:` is required prefix
* `name` is your secret name (e.g., `stripe_prod_key`)

**Common header patterns:**

**Bearer token:**

```json theme={"dark"}
{
  "Authorization": "Bearer {{secret:api_key}}"
}
```

**API key header:**

```json theme={"dark"}
{
  "X-API-Key": "{{secret:sendgrid_key}}"
}
```

**Basic auth:**

```json theme={"dark"}
{
  "Authorization": "Basic {{secret:base64_credentials}}"
}
```

**Custom header:**

```json theme={"dark"}
{
  "X-Webhook-Secret": "{{secret:webhook_secret}}",
  "X-App-ID": "{{secret:app_id}}"
}
```

### Step 3: Or Inject Secret in Body

For POST/PUT/PATCH requests, inject into JSON body:

```json theme={"dark"}
{
  "api_key": "{{secret:printnode_key}}",
  "computerId": 123,
  "options": {
    "auth_token": "{{secret:auth_token}}"
  }
}
```

Secrets work in nested objects too!

### Step 4: Save Route

Click **Save Changes**

## Test Your Secret

### Make a Request

```bash theme={"dark"}
curl -X POST "https://a1b2c3d4.DunderMifflin.knoxcall.com/api/charge" \
  -H "x-knoxcall-key: tk_abc123..." \
  -H "x-knoxcall-route: stripe-payments" \
  -H "Content-Type: application/json" \
  -d '{"amount": 1000, "currency": "usd"}'
```

### What Happens

1. KnoxCall receives your request
2. Loads route "stripe-payments"
3. Sees `{{secret:stripe_prod_key}}` in header template
4. Decrypts secret server-side
5. Replaces template with actual value:
   ```text theme={"dark"}
   Authorization: Bearer sk_live_abc123xyz789...
   ```
6. Forwards request to Stripe API with real key
7. Returns response to you

**Your client never saw the Stripe key!** ✅

### View in Logs

1. Navigate to **Logs** → **API Logs**
2. Find your request
3. Click to expand details
4. Notice: Request headers show `{{secret:stripe_prod_key}}` (template)
5. But backend received actual decrypted value

Logs never expose plaintext secret values for security.

## Multiple Secrets in One Route

You can use multiple secrets in a single route:

```json theme={"dark"}
{
  "Authorization": "Bearer {{secret:stripe_key}}",
  "X-Webhook-Secret": "{{secret:webhook_secret}}",
  "X-User-ID": "{{secret:user_id}}"
}
```

Or in body:

```json theme={"dark"}
{
  "payment_key": "{{secret:stripe_key}}",
  "notification_key": "{{secret:twilio_key}}",
  "database_url": "{{secret:postgres_url}}"
}
```

All secrets are decrypted and injected in a single pass.

## Environment-Specific Secrets

Use different secrets per environment (dev/staging/prod):

### Create Environment-Specific Secrets

1. **Development:**
   * Name: `stripe_dev_key`
   * Value: `sk_test_abc123...`

2. **Staging:**
   * Name: `stripe_staging_key`
   * Value: `sk_test_xyz789...`

3. **Production:**
   * Name: `stripe_prod_key`
   * Value: `sk_live_abc123...`

### Configure Route Per Environment

**Base route (production):**

```json theme={"dark"}
{
  "Authorization": "Bearer {{secret:stripe_prod_key}}"
}
```

**Development override:**

```json theme={"dark"}
{
  "Authorization": "Bearer {{secret:stripe_dev_key}}"
}
```

**Staging override:**

```json theme={"dark"}
{
  "Authorization": "Bearer {{secret:stripe_staging_key}}"
}
```

Now each environment uses its own Stripe key automatically!

## Rotating a Secret

Updating a secret's value rotates it in place across every route that references it.

1. Navigate to **Secrets**
2. Click your secret (e.g., "stripe\_prod\_key")
3. In the **Details** tab, edit the secret value
4. Enter the new value:
   ```
   sk_live_new789xyz123abc456def789
   ```
5. Click **Save**

**What happens:**

* The encrypted value is replaced with the new one
* The new value takes effect immediately
* All routes using this secret now use the new value
* Zero downtime! No code changes needed

## Common Use Cases

### Payment APIs

```json theme={"dark"}
{
  "Authorization": "Bearer {{secret:stripe_prod_key}}"
}
```

```json theme={"dark"}
{
  "Authorization": "Bearer {{secret:paypal_access_token}}"
}
```

### Email/SMS Services

```json theme={"dark"}
{
  "Authorization": "Bearer {{secret:sendgrid_api_key}}"
}
```

```json theme={"dark"}
{
  "X-API-Key": "{{secret:twilio_auth_token}}"
}
```

### Webhooks

```json theme={"dark"}
{
  "X-Webhook-Secret": "{{secret:github_webhook_secret}}"
}
```

```json theme={"dark"}
{
  "X-Signature": "{{secret:shopify_hmac_secret}}"
}
```

### Database Credentials

```json theme={"dark"}
{
  "db_url": "{{secret:postgres_connection_string}}"
}
```

### Printing Services

```json theme={"dark"}
{
  "Authorization": "Basic {{secret:printnode_api_key}}"
}
```

## Security Best Practices

### Naming Conventions

✅ **Good names:**

```text theme={"dark"}
stripe_prod_key
sendgrid_dev_api_key
database_password_production
github_webhook_secret_staging
```

❌ **Bad names:**

```text theme={"dark"}
secret1
key
password
temp
```

Use descriptive names that indicate:

* Service (stripe, sendgrid)
* Purpose (api\_key, webhook\_secret)
* Environment (prod, staging, dev)

### Secret Rotation

**Recommended rotation schedule:**

* **Critical secrets** (payment APIs): Every 90 days
* **Less critical**: Every 180 days
* **Development**: Annually

**How to rotate:**

1. Generate new key in third-party service (Stripe, etc.)
2. Create new version in KnoxCall
3. Test in staging first
4. Deploy to production
5. Wait 24-48 hours
6. Revoke old key in third-party service

### Separation by Environment

✅ **Do:**

* Different secrets for dev/staging/prod
* Never use prod secrets in development
* Test secret rotation in staging first

❌ **Don't:**

* Reuse production secrets in development
* Share secrets across unrelated services
* Commit secrets to git (even encrypted)

### Access Control

* Only give team members access to secrets they need
* Use least privilege principle
* Audit secret access regularly
* Delete unused secrets promptly

### Monitoring

* Set up alerts for failed secret decryption
* Monitor secret usage in logs
* Track secret rotation dates
* Get notified when secrets expire

## Troubleshooting

### Secret Not Found Error

**Error:** `Secret 'stripe_key' not found`

**Causes:**

* Typo in secret name
* Secret was deleted
* Wrong syntax (forgot `secret:` prefix)

**Fix:**

1. Check secret exists: **Secrets** page
2. Verify name spelling matches exactly
3. Check template syntax: `{{secret:name}}` (not `{{name}}`)

### Template Not Replaced

**Symptoms:** Backend receives literal `{{secret:stripe_key}}` instead of actual value

**Causes:**

* Wrong template syntax
* Secret referenced but not found
* Header injection disabled

**Debug:**

1. Check logs - see what was actually sent
2. Verify template syntax is correct
3. Test secret exists and name matches
4. Check inject headers is enabled

### Wrong Value Injected

**Symptoms:** Backend gets wrong API key

**Causes:**

* Using wrong environment
* Secret not configured for environment
* Old version being used

**Fix:**

1. Check which environment request used
2. Verify secret configured for that environment
3. Check secret version (maybe need to create new version)
4. Look at logs to see which value was injected

## Next Steps

Now that you understand secrets:

<CardGroup cols={2}>
  <Card title="OAuth2 Integration" icon="key" href="/security/oauth2-flow">
    Set up OAuth with auto-refresh
  </Card>

  <Card title="Secret Best Practices" icon="shield" href="/essentials/secrets/secrets-overview">
    Advanced secret rotation & monitoring
  </Card>

  <Card title="Environment Switching" icon="layer-group" href="/getting-started/first-environment">
    Use different secrets per environment
  </Card>

  <Card title="Method-Specific Config" icon="code-branch" href="/advanced/method-specific-config">
    Different secrets per HTTP method
  </Card>
</CardGroup>

## Related Concepts

* **Environment tab**: Different secrets per dev/staging/prod
* **Template System**: `{{secret:name}}` syntax for injection
* **Encryption**: AES-256-GCM with envelope encryption
* **OAuth2 Secrets**: Automatic token refresh for OAuth flows

***

<CardGroup cols={2}>
  <Card title="📊 Statistics" icon="chart-line">
    * **Level**: beginner
    * **Time**: 10 minutes
  </Card>

  <Card title="🏷️ Tags" icon="tags">
    `secrets`, `security`, `credentials`, `encryption`, `quickstart`
  </Card>
</CardGroup>
