2
0
Files
logikonline e9b109c464
All checks were successful
Build and Release / Tests (push) Successful in 1m26s
Build and Release / Lint (push) Successful in 1m59s
Build and Release / Create Release (push) Has been skipped
docs: add comprehensive API reference documentation
Creates new API.md with complete API reference including:
- Architecture and encryption model documentation
- Installation and configuration guides
- Authentication methods and API endpoints
- Go package API documentation
- Error codes and code examples
- License tier information

Also updates README.md to reference the new API documentation.
2026-02-07 09:25:38 -05:00

17 KiB

GitCaddy Vault

Encrypted Secrets Management for GitCaddy

GitCaddy Vault is a commercial module compiled directly into GitCaddy Server that provides enterprise-grade secrets management within your GitCaddy repositories. Store, version, and securely access credentials, API keys, certificates, and other sensitive data without leaving your Git workflow.

Features

Core Capabilities

  • Encrypted Storage - All secrets encrypted at rest using AES-256-GCM with per-repository encryption keys
  • Version History - Full version tracking with rollback capability for all secrets
  • Audit Logging - Complete audit trail of all secret access and modifications
  • CI/CD Tokens - Scoped tokens for secure automated access during builds and deployments

Secret Types

Type Description
key-value Simple key-value pairs
env-file Environment file format (KEY=value)
file Arbitrary file content
certificate TLS/SSL certificates
ssh-key SSH private keys

Lockbox (End-to-End Encryption)

Lockbox provides optional client-side encryption where the server never sees your plaintext secrets. Perfect for highly sensitive data where you don't want even the server administrator to have access.

Feature Standard Mode Lockbox Mode
Server sees plaintext Yes No
Passphrase required No Yes
Recovery if passphrase lost Yes No
Web UI viewing Yes CLI/SDK only

How Lockbox Works:

  1. Client encrypts secret with your passphrase using Argon2id + AES-256-GCM
  2. Encrypted blob is sent to server in lockbox:v1:... format
  3. Server wraps the blob with repository DEK (double encryption)
  4. On retrieval, server unwraps DEK layer, returns lockbox blob
  5. Client decrypts with your passphrase

Encryption Scheme:

  • Key derivation: Argon2id (time=1, memory=64MB, parallelism=4)
  • Cipher: AES-256-GCM with 12-byte nonce
  • Salt: 16 bytes random per secret
  • Format: lockbox:v1:<base64(salt)>:<base64(nonce||ciphertext||tag)>

Security Architecture

┌─────────────────────────────────────────────────────────┐
│                    GitCaddy Server                       │
├─────────────────────────────────────────────────────────┤
│  ┌─────────────┐    ┌─────────────┐    ┌─────────────┐  │
│  │   Web UI    │    │   REST API  │    │  CI/CD API  │  │
│  └──────┬──────┘    └──────┬──────┘    └──────┬──────┘  │
│         │                  │                  │          │
│         └──────────────────┼──────────────────┘          │
│                            │                             │
│                   ┌────────▼────────┐                    │
│                   │  Vault Service  │                    │
│                   └────────┬────────┘                    │
│                            │                             │
│         ┌──────────────────┼──────────────────┐          │
│   ┌─────▼─────┐     ┌──────▼──────┐    ┌──────▼──────┐  │
│   │  Crypto   │     │   Models    │    │  License    │  │
│   │  Engine   │     │   (XORM)    │    │  Manager    │  │
│   └───────────┘     └─────────────┘    └─────────────┘  │
│                                                          │
│               (Compiled into GitCaddy Server)            │
└─────────────────────────────────────────────────────────┘

Encryption Hierarchy:

  1. Master Key (KEK) - Server-level key encryption key
  2. Repository DEK - Per-repository data encryption key, encrypted by KEK
  3. Secret Values - Encrypted using repository DEK with AES-256-GCM

Installation

Requirements

  • GitCaddy Server v1.0.0 or later (Vault is included automatically)
  • Valid GitCaddy Vault license

Setup

GitCaddy Vault is compiled directly into GitCaddy Server - no separate installation required.

  1. Add your license key via environment variable or file:

    # Option 1: Environment variable
    export GITCADDY_LICENSE_KEY="<your-base64-license>"
    
    # Option 2: License file
    cp license.key /etc/gitcaddy/license.key
    
  2. Restart GitCaddy Server to activate the license

Configuration

Environment Variables

Variable Description Default
GITCADDY_LICENSE_KEY Base64-encoded license key -
GITCADDY_LICENSE_FILE Path to license file /etc/gitcaddy/license.key
GITCADDY_VAULT_KEK Master key encryption key (32 bytes, hex) Auto-generated
GITCADDY_DEV_MODE Skip license validation (dev only) 0

License File Locations

GitCaddy Server searches for license files in this order:

  1. Path specified by GITCADDY_LICENSE_FILE
  2. /etc/gitcaddy/license.key
  3. ./custom/license.key
  4. ./license.key

Usage

Web Interface

Access the Vault tab in any repository where you have admin permissions:

https://your-gitcaddy-instance/owner/repo/vault

Managing Secrets:

  1. Navigate to Repository > Vault > Secrets
  2. Click "New Secret" to create a secret
  3. Use dot notation for organization: prod.database.password, staging.api.key

Creating CI/CD Tokens:

  1. Navigate to Repository > Vault > CI/CD Tokens
  2. Click "New Token"
  3. Define the scope (e.g., read:*, read:prod.*, write:db.credentials)
  4. Set expiration time
  5. Copy the token immediately (shown only once)

REST API

All API endpoints require a valid vault token in the Authorization header.

Authentication:

# Bearer token format
Authorization: Bearer gvt_abc123...

# Or token format
Authorization: token gvt_abc123...

List Secrets:

curl -H "Authorization: Bearer $VAULT_TOKEN" \
  https://gitcaddy.example.com/api/v1/repos/owner/repo/vault/secrets

Get Secret Value:

curl -H "Authorization: Bearer $VAULT_TOKEN" \
  https://gitcaddy.example.com/api/v1/repos/owner/repo/vault/secrets/prod.database.password

Create Secret:

curl -X POST \
  -H "Authorization: Bearer $VAULT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "prod.database.password",
    "description": "Production database credentials",
    "type": "key-value",
    "value": "secret-password-here"
  }' \
  https://gitcaddy.example.com/api/v1/repos/owner/repo/vault/secrets

Update Secret:

curl -X PUT \
  -H "Authorization: Bearer $VAULT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "key-value",
    "value": "new-secret-value",
    "comment": "Rotated credentials"
  }' \
  https://gitcaddy.example.com/api/v1/repos/owner/repo/vault/secrets/prod.database.password

Delete Secret:

curl -X DELETE \
  -H "Authorization: Bearer $VAULT_TOKEN" \
  https://gitcaddy.example.com/api/v1/repos/owner/repo/vault/secrets/prod.database.password

CI/CD Integration

GitHub Actions / Gitea Actions:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Fetch secrets
        run: |
          DB_PASSWORD=$(curl -s -H "Authorization: Bearer ${{ secrets.VAULT_TOKEN }}" \
            "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/vault/secrets/prod.database.password" \
            | jq -r '.value')
          echo "::add-mask::$DB_PASSWORD"
          echo "DB_PASSWORD=$DB_PASSWORD" >> $GITHUB_ENV

GitLab CI:

deploy:
  script:
    - |
      export DB_PASSWORD=$(curl -s -H "Authorization: Bearer $VAULT_TOKEN" \
        "$CI_SERVER_URL/api/v1/repos/$CI_PROJECT_PATH/vault/secrets/prod.database.password" \
        | jq -r '.value')

Token Scopes

Token scopes control access to secrets using a simple grammar:

Scope Description
read:* Read access to all secrets
write:* Read and write access to all secrets
read:prod.* Read access to secrets starting with prod.
write:db.credentials Write access to specific secret db.credentials
admin Full administrative access

Multiple scopes: Separate with commas: read:prod.*,write:staging.*

License Tiers

Feature Solo Pro Team Enterprise
Users 1 5 25 Unlimited
Secrets per repo 5 Unlimited Unlimited Unlimited
Audit retention 7 days 90 days 1 year Custom
Version history No Yes Yes Yes
CI/CD tokens No Yes Yes Yes
SSO integration No No Yes Yes
Priority support No No No Yes

Database Schema

GitCaddy Vault uses the following tables:

  • vault_secret - Secret metadata
  • vault_secret_version - Versioned secret values (encrypted)
  • vault_repo_key - Per-repository encryption keys
  • vault_token - CI/CD access tokens
  • vault_audit_entry - Audit log entries

Development

Architecture: Vault ↔ Server Sync

Important for contributors and AI assistants:

GitCaddy Vault is the source of truth for vault-related templates and locales. Due to Go plugin compilation limitations, vault code is compiled directly into GitCaddy Server rather than loaded as a dynamic plugin.

┌─────────────────────────────────────────────────────────────────┐
│                     gitcaddy-vault (this repo)                   │
│  SOURCE OF TRUTH for:                                           │
│  • templates/repo/vault/*.tmpl  → UI templates                  │
│  • locale/*.json                → Translation strings           │
│  • models/, services/, crypto/  → Business logic                │
│  • license/                     → License validation            │
└─────────────────────────┬───────────────────────────────────────┘
                          │
                    BUILD TIME SYNC
                    (scripts/sync-vault.sh)
                          │
                          ▼
┌─────────────────────────────────────────────────────────────────┐
│                     gitcaddy-server                              │
│  RECEIVES from vault:                                           │
│  • templates/repo/vault/*.tmpl  ← Copied from vault             │
│  • options/locale/*.json        ← vault.* keys merged           │
│                                                                  │
│  SERVER-ONLY (not in vault):                                    │
│  • templates/repo/vault/feature_upgrade.tmpl                    │
│  • templates/repo/vault/not_installed.tmpl                      │
│  • templates/repo/vault/upgrade.tmpl                            │
│  • routers/web/repo/vault/vault.go  ← Router glue code          │
│  • services/vault/vault.go          ← Service wrappers          │
└─────────────────────────────────────────────────────────────────┘

When making changes:

  • Edit templates/locales in gitcaddy-vault (this repo)
  • The CI build automatically syncs to gitcaddy-server
  • Server-specific templates (upgrade prompts) stay in server repo
  • Go router code stays in server repo (thin integration layer)

Why not Go plugins? Go plugins require exact compiler version and dependency matches between plugin and host. This is fragile in practice, so we compile vault directly into the server binary.

Building

The Vault module is compiled directly into GitCaddy Server. To build the server with Vault:

# Clone GitCaddy Server (includes Vault)
git clone https://git.marketally.com/gitcaddy/server.git
cd server

# Build the server (Vault is included automatically)
make build

# Run tests
go test ./...

Keygen Utility

The license key generation tool is built separately:

# Clone the vault repository
git clone https://git.marketally.com/gitcaddy/vault.git
cd vault

# Build the keygen utility
go build -o keygen ./cmd/keygen

Generating License Keys

# Generate a new keypair (do this once, keep private key secure!)
go run ./cmd/keygen -generate-keys

# Sign a license
go run ./cmd/keygen -sign \
  -email customer@example.com \
  -tier pro \
  -duration 365d \
  -private-key /secure/path/private.key

Local Development

Set GITCADDY_DEV_MODE=1 to skip license validation during development:

export GITCADDY_DEV_MODE=1

Key Management

Master Key Configuration

The vault uses a master Key Encryption Key (KEK) to encrypt repository-level Data Encryption Keys (DEKs). Configure the master key using one of these methods (in priority order):

  1. app.ini (recommended for production):

    [vault]
    MASTER_KEY = <64-character-hex-string>
    
  2. Environment variable:

    export GITCADDY_VAULT_KEY="<64-character-hex-string>"
    
  3. Key file:

    export GITCADDY_VAULT_KEY_FILE="/etc/gitcaddy/vault.key"
    
  4. Fallback (not recommended): If none of the above are set, Gitea's SECRET_KEY is used as a fallback.

Generate a secure master key:

openssl rand -hex 32

Key Migration

If you change your master key or need to migrate from the fallback key to a dedicated master key, use the Key Migration feature.

When to use key migration:

  • You changed the MASTER_KEY in app.ini and existing secrets are now inaccessible
  • Secrets were created using the fallback key before a dedicated master key was configured
  • You see "Encryption Key Mismatch" errors when accessing vault secrets

Web UI:

  1. Navigate to Repository > Vault > Key Migration (admin only)
  2. Enter the old master key (the previous MASTER_KEY or Gitea's SECRET_KEY)
  3. Choose the migration scope (this repository or all repositories)
  4. Click "Start Migration"

API:

curl -X POST \
  -H "Authorization: Bearer $VAULT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "old_key": "<previous-master-key-or-secret-key>",
    "repo_id": 0
  }' \
  https://gitcaddy.example.com/owner/repo/-/vault/api/migrate-key

The old_key can be:

  • A 64-character hex string (will be decoded to 32 bytes)
  • Raw text (will be used as-is, padded/truncated to 32 bytes)

Set repo_id to 0 to migrate the current repository, or specify a repo ID for a specific repository. Instance admins can migrate all repositories at once.

DEK Rotation (Enterprise)

For enhanced security, Enterprise license holders can rotate the Data Encryption Key (DEK) for a repository. This generates a new DEK and re-encrypts all secret versions.

Web UI:

  1. Navigate to Repository > Vault > Key Migration
  2. Click "Rotate DEK" in the DEK Rotation section

API:

curl -X POST \
  -H "Authorization: Bearer $VAULT_TOKEN" \
  https://gitcaddy.example.com/owner/repo/-/vault/api/rotate-key

Security Considerations

  1. Key Management - The master KEK should be stored securely (HSM, KMS, or secure environment variable)
  2. Token Storage - Vault tokens are hashed with SHA-256 before storage
  3. Audit Trail - All access is logged with IP address and user information
  4. Soft Delete - Deleted secrets are retained for recovery before permanent deletion
  5. TLS Required - Always use HTTPS in production

Support

License

Business Source License 1.1 - See LICENSE file for details.

Copyright 2026 MarketAlly. All rights reserved.