Using Secrets in Julep

This guide will walk you through the process of creating, managing, and using secrets in your Julep applications. Secrets provide a secure way to store and use sensitive information like API keys, credentials, and tokens without exposing them in your code or configuration files.

Creating Secrets

You can create secrets using the Julep CLI, SDKs, or directly through the API.

Using the CLI

# Create a new secret
julep secrets create --name "openai_api_key" --value "sk-..." --description "OpenAI API key for production"

# List all secrets
julep secrets list

# Get a specific secret
julep secrets get openai_api_key

Using the Python SDK

from julep import Julep

client = Julep(api_key="your_api_key")

# Create a secret
client.secrets.create(
    name="openai_api_key",
    value="sk-...",
    description="OpenAI API key for production"
)

# List all secrets
secrets = client.secrets.list()
for secret in secrets.items:
    print(f"{secret.name}: {secret.description}")

Using the Node.js SDK

import { Julep } from '@julep/sdk';

const julep = new Julep({ apiKey: 'your_api_key' });

// Create a secret
await julep.secrets.create({
  name: 'openai_api_key',
  value: 'sk-...',
  description: 'OpenAI API key for production'
});

// List all secrets
const secrets = await julep.secrets.list();
secrets.items.forEach(secret => {
  console.log(`${secret.name}: ${secret.description}`);
});

Using the REST API

You can also create secrets directly using the REST API:

curl -X POST "https://api.julep.ai/v1/secrets/{developer_id}" \
  -H "Authorization: Bearer {api_key}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "openai_api_key",
    "value": "sk-...",
    "description": "OpenAI API key for production"
  }'

Using Secrets in Tasks

Once you’ve created secrets, you can reference them in your tasks using the secret_name field or the secrets object.

Direct Secret Reference

For tools that require a single API key or token:

steps:
  - kind: tool_call
    tool: openai
    operation: chat
    arguments:
      model: "gpt-4"
      messages:
        - role: "user"
          content: "What's the weather like in San Francisco?"
    secret_name: openai_api_key

Multiple Secrets

For tools that require multiple secrets:

steps:
  - kind: tool_call
    tool: email
    operation: send
    arguments:
      to: "recipient@example.com"
      subject: "Hello from Julep"
      body: "This is a test email sent from Julep."
    secrets:
      service_api_key: "email_service_api_key"
      sender_address: "email_sender_address"

Using Secrets in Expressions

You can reference secrets in expressions using the secrets object:

steps:
  - kind: transform
    expression: "$ f'https://api.example.com/v1?api_key={secrets.api_key}&query={input}'"
    input: "search query"
    output: api_url

For template variables in prompts:

steps:
  - kind: prompt
    model: gpt-4
    prompt: "Access the database at {{ db_url }} with credentials {{ credentials }}"
    template_variables:
      db_url: "$ secrets.db_host"
      credentials: "$ f'User: {secrets.db_username}, Password: {secrets.db_password}'"

Managing Secrets

Updating Secrets

To update an existing secret:

# CLI
julep secrets update openai_api_key --value "new-sk-..."

# Python SDK
client.secrets.update(
    name="openai_api_key",
    value="new-sk-..."
)

# Node.js SDK
await julep.secrets.update({
  name: 'openai_api_key',
  value: 'new-sk-...'
});

Adding Metadata

You can add metadata to organize and categorize your secrets:

client.secrets.create(
    name="stripe_api_key",
    value="sk_test_...",
    description="Stripe API key for payment processing",
    metadata={
        "environment": "production",
        "owner": "payments-team",
        "rotation_date": "2025-05-10"
    }
)

This metadata can be used for filtering when listing secrets:

production_secrets = client.secrets.list(
    metadata={"environment": "production"}
)

Deleting Secrets

When a secret is no longer needed:

# CLI
julep secrets delete openai_api_key

# Python SDK
client.secrets.delete(name="openai_api_key")

# Node.js SDK
await julep.secrets.delete({ name: 'openai_api_key' });

Common Use Cases

Securing LLM API Keys

Julep can automatically use developer secrets for LLM API keys based on the provider:

# Store the API key as a secret
client.secrets.create(
    name="OPENAI_API_KEY",
    value="sk-..."
)

# The key will be automatically used for OpenAI requests
task = client.tasks.create({
    "steps": [
        {
            "kind": "prompt",
            "model": "gpt-4",
            "prompt": "Generate a story about space exploration."
        }
    ]
})

External API Integration

For tools that call external APIs:

steps:
  - kind: tool_call
    tool: api
    operation: request
    arguments:
      method: "GET"
      url: "https://api.example.com/data"
      headers:
        Authorization: "$ f'Bearer {secrets.api_token}'"
        X-API-Key: "$ secrets.api_key"

Database Connections

For database operations:

steps:
  - kind: tool_call
    tool: postgres
    operation: query
    arguments:
      query: "SELECT * FROM users LIMIT 10"
      connection:
        host: "$ secrets.pg_host"
        user: "$ secrets.pg_user"
        password: "$ secrets.pg_password"
        database: "$ secrets.pg_database"

Best Practices

  1. Never commit secrets to version control
  2. Use descriptive names for your secrets
  3. Add metadata to organize your secrets
  4. Rotate secrets regularly
  5. Use the minimum necessary permissions
  6. Delete unused secrets promptly
  7. Use secret references instead of hardcoding values

Next Steps