2
0
Files
gitcaddy-vault/README.md
logikonline 9cfa9ebc82 docs: Add architecture documentation for vault-server sync
Explains that vault is source of truth for templates/locales,
and server syncs from vault at build time via sync-vault.sh.
Documents why Go plugins aren't used (compilation requirements).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 17:11:06 -05:00

13 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

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

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.