Authentication

Note: Registry publishing and private resources require the marketplace backend to be deployed. GitHub authentication is fully functional.

Authentication is required for publishing packages, sharing environments, and accessing private registry resources. HORUS uses GitHub OAuth for interactive login and API keys for automated systems.

Overview

Authentication methods:

  • GitHub OAuth - Interactive login via browser (recommended for development)
  • API Keys - Long-lived tokens for CI/CD and automation
  • Environment Variables - For containerized deployments

What requires authentication:

  • Publishing packages (horus pkg publish)
  • Publishing environments (horus env freeze --publish)
  • Accessing private packages
  • Managing your published packages

What doesn't require authentication:

  • Installing public packages (horus pkg install)
  • Searching registry (horus pkg list)
  • Restoring public environments (horus env restore)
  • Using installed packages

Quick Start

Interactive Login

# Login with GitHub
horus auth login --github

What happens:

  1. Opens browser to GitHub OAuth page
  2. You authorize HORUS Registry
  3. Token saved to ~/.horus/credentials
  4. Ready to publish!

Check Authentication

# Verify you're logged in
horus auth whoami

Output:

Authenticated as: your-username
Email: you@example.com
GitHub: https://github.com/your-username
Provider: GitHub OAuth
Token: ****...****abcd
Expires: Never (refresh handled automatically)

Logout

# Remove credentials
horus auth logout

GitHub OAuth Login

First-Time Setup

Step-by-step:

# 1. Run login command
horus auth login --github

Output:

Opening GitHub OAuth page in browser...

If browser doesn't open automatically, visit:
  https://github.com/login/oauth/authorize?client_id=...

Waiting for authorization...

In browser:

  1. See "Authorize HORUS Registry" page
  2. Review permissions requested:
    • Read user profile
    • Read email address
  3. Click "Authorize horus-registry"
  4. Redirected to success page

Back in terminal:

 Authorization successful!
 Token saved to ~/.horus/credentials

Authenticated as: your-username
Email: you@example.com

You can now publish packages with:
  horus pkg publish

What Gets Stored

Credentials file: ~/.horus/credentials

{
  "provider": "github",
  "username": "your-username",
  "email": "you@example.com",
  "token": "gho_abc123def456...",
  "refresh_token": "gho_xyz789...",
  "expires_at": null,
  "created_at": "2025-10-09T14:30:00Z"
}

Security:

  • File permissions: 0600 (read/write owner only)
  • Tokens encrypted at rest
  • Auto-refresh before expiration
  • Revocable via GitHub settings

Token Permissions

Required scopes:

  • read:user - Read your GitHub profile
  • user:email - Read your email address

Not requested:

  • No write access to repositories
  • No access to private repositories
  • No access to organizations

Revoking Access

Via GitHub:

  1. Go to https://github.com/settings/applications
  2. Find "HORUS Registry" under "Authorized OAuth Apps"
  3. Click "Revoke"

Via CLI:

horus auth logout

API Keys

API keys are long-lived tokens for automated systems like CI/CD pipelines.

Generating API Keys

Interactive generation:

horus auth generate-key

Interactive prompts:

Generating API key...

Key name (for identification): CI/CD Pipeline
Environment (optional): production
Description (optional): GitHub Actions deployment

Generated API key:
  horus_live_abc123def456ghi789jkl012mno345pqr678stu901

WARNING: WARNING: Copy this key now. It won't be shown again.

Save to environment variable:
  export HORUS_API_KEY=horus_live_abc123def456ghi789jkl012mno345pqr678stu901

Or use in CI:
  # GitHub Actions
  - name: Publish
    env:
      HORUS_API_KEY: ${{ secrets.HORUS_API_KEY }}
    run: horus pkg publish

With flags:

horus auth generate-key \
  --name "GitHub Actions" \
  --environment "production"

Using API Keys

Environment variable (recommended):

# Set for session
export HORUS_API_KEY=horus_live_abc123...

# Use horus commands
horus pkg publish

Credentials file:

# Save to file manually
echo '{"api_key":"horus_live_abc123..."}' > ~/.horus/credentials

Note: Managing API keys (listing, revoking, etc.) is currently done through the registry web interface at https://marketplace.horus-registry.dev

CI/CD Integration

GitHub Actions

Workflow file (.github/workflows/publish.yml):

name: Publish to HORUS Registry

on:
  push:
    tags:
      - 'v*'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Install Rust
        uses: actions-rs/toolchain@v1
        with:
          toolchain: stable

      - name: Install HORUS
        run: |
          cargo install horus_manager

      - name: Publish Package
        env:
          HORUS_API_KEY: ${{ secrets.HORUS_API_KEY }}
        run: |
          horus pkg publish --yes

      - name: Publish Environment
        env:
          HORUS_API_KEY: ${{ secrets.HORUS_API_KEY }}
        run: |
          horus env freeze --publish \
            --name "Release ${{ github.ref_name }}"

Setup:

  1. Generate API key: horus auth generate-key --name "GitHub Actions"
  2. Copy key: horus_live_abc123...
  3. Add to GitHub secrets:
    • Go to repository Settings Secrets Actions
    • New repository secret: HORUS_API_KEY
    • Paste key value
  4. Push tag: git tag v1.0.0 && git push origin v1.0.0

GitLab CI

.gitlab-ci.yml:

publish:
  stage: deploy
  image: rust:latest
  before_script:
    - cargo install horus_manager
  script:
    - horus pkg publish --yes
  only:
    - tags
  variables:
    HORUS_API_KEY: $CI_HORUS_API_KEY

Setup:

  1. Generate key: horus auth generate-key --name "GitLab CI"
  2. Add to GitLab:
    • Settings CI/CD Variables
    • Key: CI_HORUS_API_KEY
    • Value: horus_live_abc123...
    • Type: Masked

Docker

Dockerfile:

FROM rust:1.70

# Install HORUS
RUN cargo install horus_manager

# Copy project
COPY . /app
WORKDIR /app

# Build and publish
ARG HORUS_API_KEY
ENV HORUS_API_KEY=${HORUS_API_KEY}

RUN horus pkg publish --yes

Build:

docker build \
  --build-arg HORUS_API_KEY=$HORUS_API_KEY \
  -t my-horus-app .

Jenkins

Jenkinsfile:

pipeline {
    agent any

    environment {
        HORUS_API_KEY = credentials('horus-api-key')
    }

    stages {
        stage('Build') {
            steps {
                sh 'cargo build --release'
            }
        }

        stage('Publish') {
            when {
                buildingTag()
            }
            steps {
                sh 'horus pkg publish --yes'
            }
        }
    }
}

Setup:

  1. Generate key: horus auth generate-key --name "Jenkins"
  2. Jenkins dashboard Manage Jenkins Credentials
  3. Add secret text credential: horus-api-key

Environment Variables

Available Variables

HORUS_API_KEY

  • API key for authentication
  • Overrides credentials file
  • Required for CI/CD

HORUS_REGISTRY_URL

  • Custom registry URL
  • Default: https://marketplace.horus-registry.dev
  • For self-hosted or custom registries

HORUS_TOKEN

  • OAuth token (alternative to API key)
  • Not recommended for CI/CD

Example usage:

export HORUS_API_KEY=horus_live_abc123...
export HORUS_REGISTRY_URL=https://custom-registry.company.com

horus pkg publish

Security Best Practices

Token Security

Do's:

  • Use API keys for CI/CD (not OAuth tokens)
  • Rotate keys every 90 days
  • Use different keys for different environments
  • Store keys in CI/CD secrets management
  • Revoke unused keys immediately
  • Use environment variables (not command-line flags)

Don'ts:

  • Never commit credentials to git
  • Never share API keys between team members
  • Never log API keys
  • Never use same key for prod and dev
  • Never hardcode keys in source code

Credentials File Security

File permissions:

# Verify permissions
ls -la ~/.horus/credentials
# Should show: -rw------- (600)

# Fix if needed
chmod 600 ~/.horus/credentials

Backup:

# Backup credentials (encrypted)
gpg -c ~/.horus/credentials
# Creates ~/.horus/credentials.gpg

# Restore
gpg -d ~/.horus/credentials.gpg > ~/.horus/credentials
chmod 600 ~/.horus/credentials

Key Rotation

Regular rotation schedule:

# 1. Generate new key
horus auth generate-key --name "Production 2025-Q4"

# 2. Update CI/CD secrets with the new key
# (Do this manually in your CI/CD platform)

# 3. Test new key
export HORUS_API_KEY=horus_live_new_key...
horus auth whoami

# 4. Revoke old key via registry web interface
# Visit https://marketplace.horus-registry.dev to manage keys

Monitoring

Note: API key usage monitoring and alerts are managed through the registry web interface at https://marketplace.horus-registry.dev (local) or https://marketplace.horus-registry.dev (public)

Troubleshooting

Authentication Failed

Error:

Error: Authentication required
  Run: horus auth login --github

Solutions:

# Check current status
horus auth whoami

# Re-authenticate
horus auth login --github

# Verify credentials file exists
ls -la ~/.horus/credentials

Token Expired

Error:

Error: Token expired
  Please re-authenticate

Solutions:

# Re-login (auto-refreshes token)
horus auth login --github

# Or use API key instead
horus auth generate-key
export HORUS_API_KEY=horus_live_abc123...

Invalid API Key

Error:

Error: Invalid API key
  Status: 401 Unauthorized

Causes:

  • Key was revoked
  • Key expired
  • Typo in key value
  • Wrong registry URL

Solutions:

# Verify key format
echo $HORUS_API_KEY
# Should start with: horus_live_

# Check key status via registry web interface
# Visit https://marketplace.horus-registry.dev or https://marketplace.horus-registry.dev

# Generate new key
horus auth generate-key

Permission Denied

Error:

Error: Permission denied
  You don't have permission to publish to this package

Causes:

  • Package owned by another user
  • Not logged in
  • Insufficient permissions

Solutions:

# Verify authentication
horus auth whoami

# Check package ownership via registry web interface
# Visit https://marketplace.horus-registry.dev or https://marketplace.horus-registry.dev

# For package ownership transfer, contact registry support

GitHub OAuth Failed

Error:

Error: OAuth authorization failed
  Could not complete GitHub authentication

Solutions:

# Try manual flow
horus auth login --github --no-browser

# Output:
Visit this URL: https://github.com/login/oauth/authorize?client_id=...

# Check browser popup blockers

# Verify GitHub account
curl https://api.github.com/user \
  -H "Authorization: Bearer <your-github-token>"

Advanced Topics

Self-Hosted Registry

Configure custom registry:

# Set registry URL
export HORUS_REGISTRY_URL=https://registry.company.internal

# Authenticate
horus auth login --registry https://registry.company.internal

# Use as normal
horus pkg publish

Multiple Accounts

Switch between accounts:

# Save current credentials
mv ~/.horus/credentials ~/.horus/credentials.account1

# Login with second account
horus auth login --github

# Switch back
mv ~/.horus/credentials ~/.horus/credentials.account2
mv ~/.horus/credentials.account1 ~/.horus/credentials

Programmatic Authentication

Using Rust:

use horus_client::auth::AuthClient;

let client = AuthClient::new();

// With API key
client.authenticate_with_key("horus_live_abc123...")?;

// Check auth
let user = client.whoami()?;
println!("Authenticated as: {}", user.username);

Using Python:

from horus import AuthClient

client = AuthClient()

# With API key
client.authenticate(api_key="horus_live_abc123...")

# Check auth
user = client.whoami()
print(f"Authenticated as: {user['username']}")

Next Steps