Skip to main content

Environment Basics

Environments in KnoxCall allow you to manage different configurations (dev, staging, production) for the same route without duplicating everything.

What is an Environment?

An environment is a configuration context that determines which settings to use for a route. Think of it as a profile or mode.

Real-World Analogy

Imagine a light switch with multiple modes:
  • “Day” mode → Bright lights, full power
  • “Night” mode → Dim lights, low power
  • “Movie” mode → Colored lights, ambient
Same switch, different settings based on the mode. Environments work the same way:
  • Production → Real API keys, production database
  • Staging → Test API keys, staging database
  • Development → Mock data, local server

Why Use Environments?

The Problem Without Environments

Without environments, you’d need separate routes for each stage:
❌ user-api-dev → https://localhost:3000
❌ user-api-staging → https://staging.api.com
❌ user-api-prod → https://api.production.com
Issues:
  • Duplicate routes to maintain
  • Easy to misconfigure
  • Hard to keep in sync
  • Route names get messy

The Solution With Environments

With environments, you have one route with different configs:
✅ user-api (base route)
  ├── production → https://api.production.com
  ├── staging → https://staging.api.com
  └── development → https://localhost:3000
Benefits:
  • Single route to maintain
  • Consistent naming
  • Easy to switch between environments
  • Clear separation of configs

How Environments Work

The Base + Override System

KnoxCall uses a base + override system:
  1. Base environment - Default configuration
  2. Override environments - Customize specific settings
Example:
Route: stripe-payments

Base (production):
  Target URL: https://api.stripe.com
  Header: Authorization: Bearer {{secret:stripe_prod_key}}
  Clients: [production-server]

Override (staging):
  Target URL: INHERIT from base ✓
  Header: Authorization: Bearer {{secret:stripe_staging_key}}  ← Override
  Clients: [staging-server, dev-laptop]  ← Override

Override (development):
  Target URL: https://stripe-sandbox.com  ← Override
  Header: INHERIT from override (staging) ✓
  Clients: [dev-laptop]  ← Override
How it works:
  • If override = null or empty → Use base value
  • If override = specific value → Use override value
  • Changes to base automatically affect overrides (unless overridden)

Default Environments

KnoxCall creates one default environment for every tenant:

Production (Base Environment)

  • Name: production
  • Type: Base
  • Purpose: Default configuration
  • Usage: If no environment specified, this is used
When you create a route, you’re actually configuring the production environment.

Common Environment Setup

Typical 3-Environment Setup

Most teams use three environments:

1. Development

  • Purpose: Local development and testing
  • Target: http://localhost:3000 or sandbox APIs
  • Secrets: Test/fake API keys
  • Clients: Developer laptops (dynamic IPs)
  • Example:
    Name: development
    Target: https://sandbox.stripe.com
    Secret: stripe_test_key
    Clients: dev-laptop-1, dev-laptop-2
    

2. Staging

  • Purpose: Pre-production testing
  • Target: Staging servers
  • Secrets: Staging API keys (real-ish data)
  • Clients: Staging servers + QA team
  • Example:
    Name: staging
    Target: https://staging-api.acme.com
    Secret: stripe_staging_key
    Clients: staging-server, qa-team-ips
    

3. Production

  • Purpose: Live customer traffic
  • Target: Production servers
  • Secrets: Production API keys (real data!)
  • Clients: Production servers only
  • Example:
    Name: production
    Target: https://api.acme.com
    Secret: stripe_prod_key
    Clients: prod-server-1, prod-server-2
    

Using Environments in Requests

Specify Environment with Header

To use a specific environment, add the header:
# Call production (default)
curl https://a1b2c3d4.acme.knoxcall.com/api/users \
  -H "x-knoxcall-route: user-api"

# Call staging explicitly
curl https://a1b2c3d4.acme.knoxcall.com/api/users \
  -H "x-knoxcall-route: user-api" \
  -H "x-knoxcall-environment: staging"

# Call development explicitly
curl https://a1b2c3d4.acme.knoxcall.com/api/users \
  -H "x-knoxcall-route: user-api" \
  -H "x-knoxcall-environment: development"

No Header = Base Environment

If you don’t specify x-knoxcall-environment, KnoxCall uses the base environment (usually production).

What Can Be Overridden?

You can override almost everything per environment:

✅ Can Override

SettingExample
Target URLhttps://api.production.com vs https://localhost:3000
HeadersDifferent API keys, auth tokens
BodyDifferent payload structures
SecretsProduction vs test secrets
ClientsProduction servers vs dev laptops
Rate limitsHigher limits in prod, lower in dev
Method configsDifferent per HTTP method

❌ Cannot Override

SettingReason
Route nameWould create confusion
Enabled/disabledApplies to all environments
HTTP methods allowedSecurity concern

Real-World Examples

Example 1: Stripe API Route

Scenario: Process payments via Stripe in all environments. Setup:
Route: stripe-payments
Methods: POST

Production (base):
  Target: https://api.stripe.com
  Header: Authorization: Bearer {{secret:stripe_prod_key}}
  Clients: [prod-payment-server]

Staging:
  Target: INHERIT ✓
  Header: Authorization: Bearer {{secret:stripe_test_key}}  ← Test key
  Clients: [staging-server, qa-laptop]

Development:
  Target: INHERIT ✓
  Header: Authorization: Bearer {{secret:stripe_test_key}}  ← Same test key
  Clients: [dev-laptop-1, dev-laptop-2, dev-laptop-3]
Result:
  • Production charges real cards with prod key
  • Staging/dev use test keys (no real charges)
  • Different client authorization per environment

Example 2: Database API

Scenario: Query user database across environments. Setup:
Route: user-database
Methods: GET, POST

Production (base):
  Target: https://prod-db.acme.com
  Header: X-API-Key: {{secret:prod_db_key}}
  Clients: [prod-api-server]

Staging:
  Target: https://staging-db.acme.com  ← Different database!
  Header: X-API-Key: {{secret:staging_db_key}}  ← Different key
  Clients: [staging-api-server]

Development:
  Target: http://localhost:5432  ← Local database
  Header: X-API-Key: {{secret:dev_db_key}}
  Clients: [ANY]  ← No IP restriction for dev
Result:
  • Each environment hits a completely different database
  • Developers work with local data
  • Staging has realistic test data
  • Production has real customer data

Example 3: Third-Party Webhooks

Scenario: Receive webhooks from Shopify. Setup:
Route: shopify-webhooks
Methods: POST

Production (base):
  Target: https://api.acme.com/webhooks/shopify
  Header: X-Shopify-Secret: {{secret:shopify_prod_secret}}
  Clients: [shopify-prod-ips]

Staging:
  Target: https://staging.acme.com/webhooks/shopify
  Header: X-Shopify-Secret: {{secret:shopify_staging_secret}}
  Clients: [shopify-staging-ips]

Development:
  Target: https://ngrok-abc123.ngrok.io/webhooks/shopify  ← Tunneled local
  Header: INHERIT ✓
  Clients: [shopify-test-ips]
Result:
  • Production webhooks go to production backend
  • Staging webhooks go to staging
  • Dev webhooks tunnel to developer’s localhost via ngrok

NULL Values = Inherit

This is a key concept: NULL or empty values inherit from the base.

Example

Base:
  Target URL: https://api.production.com
  Header: { "Authorization": "Bearer {{secret:prod_key}}" }

Override:
  Target URL: null  ← Use base (https://api.production.com)
  Header: { "Authorization": "Bearer {{secret:staging_key}}" }  ← Override
Result:
  • Target URL: https://api.production.com (inherited)
  • Header: Bearer staging_key (overridden)

Best Practices

✅ Do

1. Use descriptive environment names
✅ production, staging, development
✅ prod, stage, dev
✅ live, test, local
2. Separate secrets per environment
✅ stripe_prod_key (production)
✅ stripe_test_key (staging/dev)
3. Different client authorization
Production: Only production servers
Staging: Staging servers + QA team
Development: All developer machines
4. Test in staging first
1. Make changes in staging
2. Test thoroughly
3. Deploy to production
5. Document environment purpose
Development: Local testing, fake data
Staging: Pre-prod testing, realistic data
Production: Live customer traffic, real data

❌ Don’t

1. Don’t use production secrets in dev
❌ development: stripe_prod_key (dangerous!)
✅ development: stripe_test_key
2. Don’t allow dev IPs in production
❌ Production clients: [dev-laptop-1, dev-laptop-2]
✅ Production clients: [prod-server-1, prod-server-2]
3. Don’t mix environments
❌ Staging using production database
✅ Staging using staging database
4. Don’t skip staging
❌ Dev → Production (risky!)
✅ Dev → Staging → Production
5. Don’t use generic names
❌ env1, env2, test
✅ staging, development

When to Create New Environments

Create New Environments When:

  1. Different target systems
    • Production API vs staging API vs local dev
  2. Different credentials
    • Production keys vs test keys
  3. Different authorization
    • Production servers vs developer laptops
  4. Different teams
    • QA environment separate from dev
  5. Different regions
    • US environment vs EU environment

Don’t Create Environments For:

  1. Different features - Use different routes instead
  2. Different customers - Use route parameters or headers
  3. Different versions - Use API versioning in URLs
  4. Temporary testing - Use staging environment

Environment Workflows

Development Workflow

1. Developer creates route in UI

2. Tests in "development" environment
   curl ... -H "x-knoxcall-environment: development"

3. Works locally? → Push code to staging server

4. Test in "staging" environment
   curl ... -H "x-knoxcall-environment: staging"

5. Staging works? → Deploy to production

6. Test in "production" environment (carefully!)
   curl ... -H "x-knoxcall-environment: production"

Environment Promotion

Development:
  ✓ Local testing
  ✓ Rapid iteration

Staging:
  ✓ Integration testing
  ✓ QA approval

Production:
  ✓ Customer traffic
  ✓ Real transactions

Troubleshooting

Environment Not Found

Error:
{
  "error": "Environment 'staging' not found"
}
Solution:
  1. Go to ResourcesEnvironments
  2. Check if “staging” exists
  3. Create it if missing
  4. Verify spelling (case-sensitive)

Using Wrong Environment

Symptom: Request goes to wrong backend. Solution:
  1. Check x-knoxcall-environment header value
  2. Verify environment name spelling
  3. Check which environment your route is configured for

Override Not Working

Symptom: Still using base configuration despite override. Cause: Override value is null (inheritance). Solution:
  1. Edit route → Environment Overrides
  2. Set specific value (not null)
  3. Save changes

Quick Reference

ConceptExplanation
EnvironmentConfiguration context (dev, staging, prod)
Base EnvironmentDefault configuration (usually production)
OverrideEnvironment-specific customization
InheritanceNULL/empty values use base configuration
SwitchingUse x-knoxcall-environment header

Next Steps


Key Takeaway: Environments let you manage dev, staging, and production with one route instead of three. Override only what’s different, inherit the rest!