Authentication

This document covers the authentication methods for Sling API specifications. For the basic structure, see Structure.

Sling supports several authentication methods, configured under the authentication key.

⚠️ Important: It's best practice to use environment variables or secrets for sensitive values instead of hardcoding them.

Managing Secrets and Environment Variables

Sling provides flexible ways to manage sensitive authentication data through environment variables and the env.yaml file. Here's how to configure them:

Using the env.yaml File

The primary method for managing secrets is through the env.yaml file located at ~/.sling/env.yaml. When defining API connections, you can specify secrets that will be available to your API specs.

# ~/.sling/env.yaml
connections:
  my_api:
    type: api
    spec: file:///path/to/my_api.spec.yaml
    secrets:
      api_key: "your-secret-api-key"
      client_id: "your-oauth-client-id"
      client_secret: "your-oauth-client-secret"
      username: "your-username"
      password: "your-password"
      
  github_api:
    type: api
    spec: github
    secrets:
      token: "ghp_xxxxxxxxxxxxxxxxxxxx"
      
  stripe_api:
    type: api
    spec: stripe
    secrets:
      api_key: "sk_test_xxxxxxxxxxxxxxxxxxxx"

You'll be able to access the secrets values via the {secrets.var_name} expression.

# In your API spec
defaults:
  request:
    headers:
      Authorization: "Bearer {secrets.api_key}"

Using Environment Variables

You can also provide secrets via environment variables. In your API spec, use the {env.VARIABLE_NAME} syntax:

# Set environment variables
export API_USERNAME="myuser"
export API_PASSWORD="mypassword"
# In your API spec
authentication:
  type: "basic"
  username: "{env.API_USERNAME}"
  password: "{env.API_PASSWORD}"

Authentication Methods

Now that you understand how to manage secrets, here are the different authentication methods you can configure:

No Authentication

# Simply omit the authentication block for APIs that don't require authentication

Static Header Authentication

For APIs that require headers for authentication (e.g., API keys, bearer tokens):

authentication:
  type: "static"
  headers:
    Authorization: "Bearer {secrets.api_token}"

This is ideal for:

  • API keys passed in headers (e.g., X-API-Key: your-key)

  • Bearer tokens (e.g., Authorization: Bearer your-token)

  • Custom authentication headers

  • Multiple authentication headers

Examples:

# API Key in custom header
authentication:
  type: "static"
  headers:
    X-API-Key: "{secrets.api_key}"

# Bearer token
# we can omit `type: static` and only specify `headers`
authentication:
  headers:
    Authorization: "Bearer {secrets.access_token}"

# Multiple headers
authentication:
  headers:
    Authorization: "Bearer {secrets.access_token}"
    X-API-Key: "{secrets.api_key}"
    X-Tenant-ID: "{secrets.tenant_id}"

Shorthand Syntax:

When only headers are provided without any other authentication configuration, the type defaults to static:

# This is equivalent to type: "static"
authentication:
  headers:
    Authorization: "Bearer {secrets.api_token}"

📝 Note: For dynamic token retrieval (e.g., login flow), use the sequence authentication type instead.

Basic Auth

authentication:
  type: "basic"
  username: "{secrets.username}"
  password: "{secrets.password}"

OAuth2 Authentication

For OAuth2 flows, use the oauth2 type. Sling supports three OAuth2 flows:

Flow
Use Case
Interactive

client_credentials

Server-to-server, machine-to-machine

No

authorization_code

User-facing apps, browser-based auth

Yes

device_code

CLI tools, headless environments

Yes (on another device)

Full Property Reference:

authentication:
  type: "oauth2"
  flow: "client_credentials"  # client_credentials|authorization_code|device_code
  client_id: "{secrets.client_id}"
  client_secret: "{secrets.client_secret}"
  authentication_url: "https://api.example.com/oauth/token"      # Token endpoint (required)
  authorization_url: "https://api.example.com/oauth/authorize"   # Auth endpoint (for authorization_code)
  device_auth_url: "https://api.example.com/oauth/device/code"   # Device auth endpoint (for device_code)
  redirect_uri: "http://localhost:8080/callback"                 # Redirect URI (for authorization_code)
  scopes:
    - "read:data"
    - "write:data"

Token Persistence: Sling automatically stores OAuth tokens in ~/.sling/api/tokens/{connection_name}.json and refreshes them when they expire. You don't need to manage token refresh manually.

PKCE Support: For public clients (when client_secret is empty), Sling automatically enables PKCE (Proof Key for Code Exchange) for added security.

Client Credentials Flow (Server-to-Server):

The most common flow for automated data pipelines. No user interaction required.

authentication:
  type: "oauth2"
  flow: "client_credentials"
  client_id: "{secrets.client_id}"
  client_secret: "{secrets.client_secret}"
  authentication_url: "https://api.example.com/oauth/token"
  scopes:
    - "read:data"

Authorization Code Flow (Browser-Based):

For user-interactive authentication. Sling opens a browser for authorization and handles the callback automatically.

authentication:
  type: "oauth2"
  flow: "authorization_code"
  client_id: "{secrets.client_id}"
  client_secret: "{secrets.client_secret}"
  authentication_url: "https://api.example.com/oauth/token"
  authorization_url: "https://api.example.com/oauth/authorize"
  scopes:
    - "read:data"

Device Code Flow (Headless/CLI):

For environments without a browser. Sling displays a URL and code for the user to enter on another device.

authentication:
  type: "oauth2"
  flow: "device_code"
  client_id: "{secrets.client_id}"
  authentication_url: "https://api.example.com/oauth/token"
  device_auth_url: "https://api.example.com/oauth/device/code"
  scopes:
    - "read:data"

AWS Signature V4 Authentication

For AWS services that require Signature V4 authentication (e.g., S3, AppSync, API Gateway):

authentication:
  type: "aws-sigv4"
  aws_service: "execute-api"  # The AWS service name (e.g., s3, execute-api, appsync)
  aws_region: "{env.AWS_REGION}"
  aws_access_key_id: "{secrets.aws_access_key_id}"
  aws_secret_access_key: "{secrets.aws_secret_access_key}"
  aws_session_token: "{secrets.aws_session_token}"  # Optional, for temporary credentials
  aws_profile: "{env.AWS_PROFILE}"  # Optional, use AWS profile instead of explicit keys

📝 Note: For AWS authentication, you can use either explicit credentials (aws_access_key_id, aws_secret_access_key) or AWS profiles (aws_profile). The AWS SDK credential chain is also supported.

HMAC Authentication

For APIs that require HMAC (Hash-based Message Authentication Code) request signing, such as cryptocurrency exchanges (Kraken, Binance) or custom enterprise APIs:

authentication:
  type: "hmac"
  algorithm: "sha256"  # sha256 or sha512
  secret: "{secrets.api_secret}"
  signing_string: "{http_method}{http_path}{unix_time}{http_body_sha256}"
  request_headers:
    X-Signature: "{signature}"
    X-Timestamp: "{unix_time}"
    X-API-Key: "{secrets.api_key}"
  nonce_length: 16  # Optional: generates random nonce (in bytes)

How HMAC Works:

  1. A signing string is constructed from request components (method, path, timestamp, body hash, etc.)

  2. The string is signed using HMAC-SHA256 or HMAC-SHA512 with your secret key

  3. The signature and related headers are automatically added to each request

Available Variables for Signing:

  • http_method - HTTP method (GET, POST, etc.)

  • http_path - Request path with query parameters

  • http_query - Canonical query string (sorted alphabetically by key)

  • http_headers - Canonical headers (lowercase, sorted, newline-separated)

  • http_body_raw - Raw request body as string

  • http_body_md5 - MD5 hash of request body (hex-encoded)

  • http_body_sha1 - SHA1 hash of request body (hex-encoded)

  • http_body_sha256 - SHA256 hash of request body (hex-encoded)

  • http_body_sha512 - SHA512 hash of request body (hex-encoded)

  • unix_time - Unix timestamp in seconds

  • unix_time_ms - Unix timestamp in milliseconds

  • date_iso - ISO 8601 formatted date (e.g., "2023-10-31T15:30:32Z")

  • date_rfc1123 - RFC 1123 formatted date (e.g., "Tue, 31 Oct 2023 15:30:32 GMT")

  • nonce - Random hex string (if nonce_length is set)

  • signature - Computed HMAC signature (hex-encoded, only available in request_headers)

Example: Kraken-style Authentication

authentication:
  type: "hmac"
  algorithm: "sha256"
  secret: "{secrets.api_secret}"
  signing_string: "{http_method}{http_path}{nonce}{http_body_sha256}"
  request_headers:
    API-Key: "{secrets.api_key}"
    API-Sign: "{signature}"
    API-Nonce: "{nonce}"
  nonce_length: 16

📝 Note: The signing_string and request_headers templates support all Sling template variables including {secrets.*}, {env.*}, and {state.*}.

Sequence Authentication (Custom Workflows)

For APIs requiring a custom authentication sequence (e.g., multi-step login), use the sequence type. This allows defining a series of API calls to obtain authentication tokens or session data.

authentication:
  type: "sequence"
  expires: 3600   # re-auth every 1 hr
  sequence:
    - request:
        url: "/login"
        method: POST
        payload:
          site_id: "{secrets.site_id}"
          user_id: "{secrets.user_id}"
          password: "{secrets.password}"
      response:
        processors:
          - expression: "response.json.token"
            output: "state.token"   # you can use this in you main request block
            aggregation: last

This performs a login request and extracts the token into state.token for use in subsequent requests. See Requests & Responses for more on sequences.

Endpoint-Level Authentication

By default, all endpoints use the authentication configured at the spec level. However, individual endpoints can override or disable authentication.

Overriding Authentication

An endpoint can specify its own authentication that overrides the spec-level configuration:

authentication:
  type: "basic"
  username: "{secrets.username}"
  password: "{secrets.password}"

endpoints:
  # Uses spec-level basic auth
  users:
    request:
      url: "{state.base_url}/users"

  # Uses its own OAuth2 auth instead
  admin_data:
    authentication:
      type: "oauth2"
      flow: "client_credentials"
      client_id: "{secrets.admin_client_id}"
      client_secret: "{secrets.admin_client_secret}"
      authentication_url: "https://api.example.com/oauth/token"
    request:
      url: "{state.base_url}/admin/data"

Disabling Authentication

Some endpoints (like health checks or public data) may not require authentication. Set authentication: null to disable it:

authentication:
  type: "oauth2"
  # ... OAuth config for most endpoints

endpoints:
  # No authentication needed for health check
  health:
    authentication: null
    request:
      url: "{state.base_url}/health"

  # Uses spec-level OAuth2
  protected_data:
    request:
      url: "{state.base_url}/data"

Authentication Expiry

The expires property can be used with any authentication type to force re-authentication after a specified number of seconds. This is useful when tokens or sessions have a fixed lifetime.

authentication:
  type: "basic"
  username: "{secrets.username}"
  password: "{secrets.password}"
  expires: 3600  # Re-authenticate every hour

When authentication expires, Sling automatically re-authenticates before the next request. This happens transparently without interrupting data extraction.

Authentication Method Comparison

Method
Best For
Auto-Refresh
Interactive

static

API keys, bearer tokens

N/A

No

basic

Username/password APIs

N/A

No

oauth2

Modern APIs, delegated auth

Yes

Depends on flow

aws-sigv4

AWS services

Yes

No

hmac

Crypto exchanges, signed requests

N/A

No

sequence

Custom auth workflows

No (use expires)

No

Last updated

Was this helpful?