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:
- Opens browser to GitHub OAuth page
- You authorize HORUS Registry
- Token saved to
~/.horus/credentials - 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:
- See "Authorize HORUS Registry" page
- Review permissions requested:
- Read user profile
- Read email address
- Click "Authorize horus-registry"
- 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 profileuser: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:
- Go to https://github.com/settings/applications
- Find "HORUS Registry" under "Authorized OAuth Apps"
- 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:
- Generate API key:
horus auth generate-key --name "GitHub Actions" - Copy key:
horus_live_abc123... - Add to GitHub secrets:
- Go to repository Settings Secrets Actions
- New repository secret:
HORUS_API_KEY - Paste key value
- 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:
- Generate key:
horus auth generate-key --name "GitLab CI" - 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:
- Generate key:
horus auth generate-key --name "Jenkins" - Jenkins dashboard Manage Jenkins Credentials
- 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
- Package Management - Publish, discover, and install packages
- Remote Deployment - Deploy to remote robots
- CLI Reference - Complete command documentation