Authentication & Credential Management

xplainpy provides multiple ways to authenticate with Xplain servers, including password-based and JWT token-based authentication. It supports secure credential storage through config files, environment variables, and profile-based management for multiple environments.

Authentication Methods

Password Authentication

Traditional username/password authentication:

from xplain import Xsession

session = Xsession(
    url="http://localhost:8080",
    user="username",
    password="password"
)

JWT Token Authentication

JSON Web Token (JWT) based authentication for SSO and enterprise identity providers:

from xplain import Xsession

session = Xsession(
    url="https://prod.company.com",
    user="username",
    jwt_dispatch_url="https://prod.company.com/jwt/dispatch",
    jwt_cookie_name="XPLAIN_JWT",
    jwt_token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
)

JWT Required Parameters:

  • jwt_dispatch_url: JWT authentication endpoint

  • jwt_cookie_name: Cookie name for JWT token

  • jwt_token: The JWT token value

If all three JWT parameters are provided, JWT authentication takes precedence over password authentication.

Credential Storage

Config File (~/.xplainpyrc)

Store credentials securely in a JSON config file:

Single Profile:

{
  "url": "http://localhost:8080",
  "user": "username",
  "password": "password"
}

Multiple Profiles:

{
  "profiles": {
    "local": {
      "url": "http://localhost:8080",
      "user": "dev-user",
      "password": "dev-password"
    },
    "staging": {
      "url": "https://staging.company.com",
      "user": "staging-user",
      "password": "staging-password"
    },
    "production-jwt": {
      "url": "https://prod.company.com",
      "user": "prod-user",
      "jwt_dispatch_url": "https://prod.company.com/jwt/dispatch",
      "jwt_cookie_name": "XPLAIN_JWT",
      "jwt_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
    }
  },
  "default": "local"
}

Security: Set appropriate permissions: chmod 600 ~/.xplainpyrc

Using Config Profiles

from xplain import create_session

# Use default profile
session = create_session()

# Use specific profile
staging = create_session(profile='staging')
prod = create_session(profile='production-jwt')

# Override profile settings
session = create_session(profile='staging', user='different-user')

Environment Variables

Store credentials in environment variables:

Default Credentials:

export XPLAIN_URL="http://localhost:8080"
export XPLAIN_USER="username"
export XPLAIN_PASSWORD="password"

# For JWT authentication
export XPLAIN_JWT_DISPATCH_URL="https://prod.com/jwt/dispatch"
export XPLAIN_JWT_COOKIE_NAME="XPLAIN_JWT"
export XPLAIN_JWT_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Profile-Specific:

# Password authentication
export XPLAIN_STAGING_URL="https://staging.company.com"
export XPLAIN_STAGING_USER="staging-user"
export XPLAIN_STAGING_PASSWORD="staging-password"

# JWT authentication
export XPLAIN_PROD_URL="https://prod.company.com"
export XPLAIN_PROD_USER="prod-user"
export XPLAIN_PROD_JWT_DISPATCH_URL="https://prod.com/jwt/dispatch"
export XPLAIN_PROD_JWT_COOKIE_NAME="XPLAIN_JWT"
export XPLAIN_PROD_JWT_TOKEN="your-token-here"
from xplain import create_session

# Uses XPLAIN_STAGING_* environment variables
session = create_session(profile='staging')

# Uses XPLAIN_PROD_JWT_* environment variables
session = create_session(profile='prod')

Config Module API

create_session

Create an Xsession with credentials from config file or environment variables:

from xplain import create_session

session = create_session(
    profile=None,           # Profile name (e.g., 'staging', 'production')
    url=None,               # Server URL (overrides profile)
    user=None,              # Username (overrides profile)
    password=None,          # Password (overrides profile)
    jwt_dispatch_url=None,  # JWT dispatch URL (overrides profile)
    jwt_cookie_name=None,   # JWT cookie name (overrides profile)
    jwt_token=None,         # JWT token (overrides profile)
    config_path=None,       # Path to config file (default: ~/.xplainpyrc)
    **kwargs                # Additional Xsession parameters
)

Examples:

# Use default credentials
session = create_session()

# Use specific profile
session = create_session(profile='production')

# Override JWT token at runtime (useful for token refresh)
session = create_session(profile='prod-jwt', jwt_token=get_fresh_token())

get_credentials

Get credentials dictionary from config/environment without creating a session:

from xplain import get_credentials

creds = get_credentials(
    url=None,
    user=None,
    password=None,
    profile=None,
    config_path=None,
    jwt_dispatch_url=None,
    jwt_cookie_name=None,
    jwt_token=None
)

# Returns dict with 'url', 'user', and either 'password' or JWT fields

Example:

from xplain import Xsession, get_credentials

creds = get_credentials(profile='staging')

# Check authentication method
if 'jwt_token' in creds:
    print("Using JWT authentication")
elif 'password' in creds:
    print("Using password authentication")

session = Xsession(**creds)

load_profile

Load a specific profile from config file:

from xplain import load_profile

creds = load_profile(
    profile_name='staging',  # Profile name (None = default profile)
    config_path=None         # Path to config (default: ~/.xplainpyrc)
)

list_profiles

List all available profiles in config file:

from xplain import list_profiles

profiles = list_profiles()
print(f"Available profiles: {', '.join(profiles)}")

# List from specific config file
profiles = list_profiles(config_path='/path/to/.xplainpyrc')

load_config_file

Load the entire config file:

from xplain import load_config_file

config = load_config_file()  # Loads from ~/.xplainpyrc

# Load from specific path
config = load_config_file('/path/to/config.json')

Credential Resolution Priority

Credentials are resolved in the following order (highest to lowest priority):

  1. Direct parameters - Values passed directly to functions

  2. Profile-specific environment variables - XPLAIN_<PROFILE>_*

  3. Profile from config file - ~/.xplainpyrcprofiles.<profile>

  4. Default environment variables - XPLAIN_*

  5. Default profile from config - ~/.xplainpyrcprofiles.default

  6. Built-in defaults - url='http://localhost:8080'

JWT Token Management

Token Refresh

JWT tokens typically expire. Refresh them at runtime:

from xplain import create_session

def get_fresh_jwt_token():
    """Get fresh token from your auth provider."""
    import requests
    response = requests.post(
        'https://auth.company.com/token',
        data={'client_id': 'xplain', 'client_secret': 'secret'}
    )
    return response.json()['access_token']

# Create session with fresh token
session = create_session(
    profile='prod-jwt',
    jwt_token=get_fresh_jwt_token()
)

Secure Token Storage

System Keyring (Recommended):

import keyring
from xplain import create_session

# Store token once
keyring.set_password("xplain-jwt", "prod", jwt_token)

# Retrieve and use
jwt_token = keyring.get_password("xplain-jwt", "prod")
session = create_session(profile='prod-jwt', jwt_token=jwt_token)

Dynamic Retrieval (Production):

from azure.identity import DefaultAzureCredential
from xplain import create_session

def get_azure_token():
    credential = DefaultAzureCredential()
    token = credential.get_token("https://your-app-id/.default")
    return token.token

session = create_session(
    profile='azure-prod',
    jwt_token=get_azure_token()
)

Security Best Practices

DO:

  • Use environment variables or config files for credentials

  • Set chmod 600 ~/.xplainpyrc (owner-only access)

  • Use different passwords/tokens per environment

  • Store JWT tokens in system keyring for long-term use

  • Rotate credentials regularly

  • Add .xplainpyrc to .gitignore

DON’T:

  • Hardcode credentials in code or notebooks

  • Commit .xplainpyrc or .env files to git

  • Share config files via email or chat

  • Use production credentials in development

  • Store credentials in code comments

Examples

Multiple Environments

from xplain import create_session

# Development with password
dev = create_session(profile='local')

# Staging with password
staging = create_session(profile='staging')

# Production with JWT
prod = create_session(profile='production-jwt')

Jupyter Notebooks

import os
from xplain import create_session

# Select environment from environment variable
env = os.getenv('ENV', 'local')
session = create_session(profile=env)

print(f"Connected to {env} environment")

CI/CD Pipelines

# Set credentials in CI/CD environment
export XPLAIN_URL="https://test.company.com"
export XPLAIN_USER="ci-user"
export XPLAIN_PASSWORD="${CI_XPLAIN_PASSWORD}"
# In your test script
from xplain import create_session

# Automatically uses CI environment variables
session = create_session()

See Also

  • Tutorial - Getting started with xplainpy

  • Core API Reference - Core API reference

  • README_PROFILES.md - Multi-environment profile management

  • README_JWT.md - JWT authentication guide