veckl

module
v0.1.0-alpha Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 30, 2026 License: Apache-2.0

README

VECKL - An Airgap Test Case Manager for GitHub/GHE

CI Go Next.js React GitHub GitHub Enterprise Server

veckl

VECKL is an airgapped, Git-backed test case management app for NIST 800-53 security control testing.

It gives teams a web UI for creating, editing, executing, and reviewing test cases while keeping GitHub or GitHub Enterprise Server as the source of truth and audit trail. Test cases are stored as Markdown files with YAML frontmatter, so the work remains portable, reviewable, and easy to track over time.

What Veckl Helps You Do

  • Manage security control test cases in a GitHub or GHES repository.
  • Select controls from a NIST 800-53-backed catalog.
  • Record test execution results step by step.
  • Review changes through Git history instead of a separate audit log.
  • Sign users in with GitHub OAuth.
  • Configure deployments through environment variables or Kubernetes Secrets.
  • Run locally, on Kubernetes, or as a Zarf package for disconnected environments.

How It Works

Veckl is split into a Go backend and a Next.js frontend:

  • Backend: Go HTTP server on http://localhost:8080
  • Frontend: Next.js app on http://localhost:3000
  • Storage: GitHub/GHES repository access through the GitHub API
  • Authentication: GitHub OAuth with encrypted session cookies
  • Configuration: Environment variables, including Kubernetes Secrets for cluster deployments

Veckl does not clone a local Git repository. All reads and writes go through the GitHub Contents API.

Requirements

For local development:

  • Go 1.22+
  • Node.js 22+
  • npm

For deployments:

  • Podman or Docker-compatible image tooling
  • Kubernetes for cluster deployments
  • Zarf for disconnected package deployment
  • A GitHub App with repository contents access
  • GitHub OAuth credentials

Local Development

Create a local .env file, generate session keys, and verify the configuration:

cp .env.template .env
./scripts/generate-session-keys.sh
./scripts/verify-env.sh .env

Start the full local stack:

make dev

Then open http://localhost:3000.

Useful local commands:

make dev-stop
make build
make run
make test
make lint
make clean

Frontend-only commands:

cd frontend
npm install
npm run dev
npm run typecheck
npm run lint
npm test

Kubernetes Deployment

Build the backend and frontend images:

make container-build
make container-build-frontend

Make the images available to your cluster, then apply the Kubernetes manifests:

kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/secret.yaml -n veckl
kubectl apply -f k8s/deployment.yaml -n veckl
kubectl apply -f k8s/service.yaml -n veckl
kubectl apply -f k8s/deployment-frontend.yaml -n veckl
kubectl apply -f k8s/service-frontend.yaml -n veckl
kubectl apply -f k8s/ingress.yaml -n veckl

Without an Ingress, port-forward the frontend service:

kubectl port-forward -n veckl service/veckl-frontend 3000:3000

Then open http://localhost:3000.

More Kubernetes details are available in k8s/README.md.

Zarf Deployment

Veckl can be packaged with Zarf for disconnected Kubernetes environments. The Zarf package includes the backend image, frontend image, and Kubernetes manifests used for the standard cluster deployment.

Create the package while connected:

make container-build
make container-build-frontend
zarf package create --confirm

Deploy the generated package in the target environment:

zarf package deploy zarf-package-veckl-*.tar.zst --confirm

After deployment, open the configured Ingress host or port-forward the frontend service as shown above.

Configuration

Required environment variables:

Variable Purpose
GITHUB_API_BASE_URL GitHub API URL. Defaults to https://api.github.com.
GITHUB_APP_ID GitHub App ID.
GITHUB_APP_INSTALLATION_ID GitHub App installation ID.
GITHUB_APP_PRIVATE_KEY_PATH Path to the GitHub App private key PEM.
GITHUB_OWNER Target repository owner.
GITHUB_REPO Target repository name.
GITHUB_BRANCH Optional target branch.
GITHUB_OAUTH_CLIENT_ID GitHub OAuth client ID.
GITHUB_OAUTH_CLIENT_SECRET GitHub OAuth client secret.
GITHUB_CA_BUNDLE_PATH Optional GHES CA bundle path.
SESSION_HASH_KEY 32-byte base64 session authentication key.
SESSION_BLOCK_KEY 32-byte base64 session encryption key.

Use scripts/generate-session-keys.sh to generate session keys.

Repository Layout

cmd/                  Go command entrypoints
internal/             Go application packages
frontend/             Next.js frontend
k8s/                  Kubernetes manifests
scripts/              Operational helper scripts used by Make targets
vendor/               Vendored Go dependencies
zarf.yaml             Zarf package definition

Air-Gapped Notes

  • Go dependencies are vendored in vendor/.
  • Build the frontend image before transfer, or use an internal npm registry mirror with NPM_REGISTRY_URL.
  • Zarf is the preferred disconnected Kubernetes deployment path.

Branch Naming

This repository follows the Conventional Branch format:

<type>/<description>

Allowed branch types are:

  • feature/ or feat/ for new features
  • bugfix/ or fix/ for bug fixes
  • hotfix/ for urgent fixes
  • release/ for release preparation
  • chore/ for non-code maintenance work
  • ai/, codex/, claude/, copilot/, or cursor/ for AI-agent work

Trunk branches main, master, and develop are also allowed without a prefix.

Use lowercase letters, numbers, hyphens, and dots only. Descriptions must not start or end with a hyphen or dot, and they must not contain consecutive hyphens or dots.

Examples:

feature/add-login-page
fix/header-bug
release/v1.2.0
chore/update-dependencies
codex/optimize-query

You can check a branch name locally with:

bash scripts/validate-branch-name.sh feature/add-login-page

License

This project is licensed under the Apache License 2.0. See LICENSE for the full license text.

Directories

Path Synopsis
cmd
catalog-import command
Command catalog-import is issue #83's operational path for populating or refreshing this project's controls catalog post-boot, without a redeploy: it reads the full NIST SP 800-53 OSCAL catalog JSON document (from a local path or a URL), projects it down to this project's flat Control list and slim, sub-1MB wire format (internal/catalog.
Command catalog-import is issue #83's operational path for populating or refreshing this project's controls catalog post-boot, without a redeploy: it reads the full NIST SP 800-53 OSCAL catalog JSON document (from a local path or a URL), projects it down to this project's flat Control list and slim, sub-1MB wire format (internal/catalog.
migrate-ids command
Command migrate-ids is Run Stage deliverable 6's combined migration tool (issue #39): a one-time, standalone CLI that assigns generated IDs (internal/idgen) to existing test-case files and moves them from the pre-Run-Stage slug-based path scheme onto the new ID-keyed one (internal/testcase.NewTestCasePath), rewriting both path and frontmatter content together in one pass.
Command migrate-ids is Run Stage deliverable 6's combined migration tool (issue #39): a one-time, standalone CLI that assigns generated IDs (internal/idgen) to existing test-case files and moves them from the pre-Run-Stage slug-based path scheme onto the new ID-keyed one (internal/testcase.NewTestCasePath), rewriting both path and frontmatter content together in one pass.
server command
Command server is the entry point for the veckl HTTP server.
Command server is the entry point for the veckl HTTP server.
testcase-import command
Command testcase-import is issue #83's operational path for seeding a batch of test-case Markdown files into the repository, so this app's targeted 50-200 test cases can be committed in one pass rather than hand-authored one at a time through the create-test-case screen.
Command testcase-import is issue #83's operational path for seeding a batch of test-case Markdown files into the repository, so this app's targeted 50-200 test cases can be committed in one pass rather than hand-authored one at a time through the create-test-case screen.
internal
auth
Package auth implements "Sign in with GitHub" user login for veckl: the OAuth 2.0 user-to-server authorization code flow for a GitHub App, plus a small stateless session mechanism built on top of it.
Package auth implements "Sign in with GitHub" user login for veckl: the OAuth 2.0 user-to-server authorization code flow for a GitHub App, plus a small stateless session mechanism built on top of it.
catalog
Package catalog provides read-only lookups against two pieces of reference data a test case can be scoped against: a user-editable component registry (config/components.yaml - see LoadComponents) and the vendored NIST SP 800-53 Rev 5 OSCAL control catalog (see LoadCatalog).
Package catalog provides read-only lookups against two pieces of reference data a test case can be scoped against: a user-editable component registry (config/components.yaml - see LoadComponents) and the vendored NIST SP 800-53 Rev 5 OSCAL control catalog (see LoadCatalog).
githubclient
Package githubclient is the sole layer through which veckl reads and writes security-control test-case files stored under /controls in a GitHub (or GitHub Enterprise Server) repository.
Package githubclient is the sole layer through which veckl reads and writes security-control test-case files stored under /controls in a GitHub (or GitHub Enterprise Server) repository.
idgen
Package idgen composes and parses the generated test-case identifiers that give each test case its stable, human-readable name: strings of the form "RHEL9-AC-02.03-001" - {COMPONENT}-{FAMILY}-{NUMBER}[.{ENHANCEMENT}]-{SEQUENCE} - built from a validated component code (internal/catalog), a resolved control (internal/catalog), and the next sequence number for that component+control pairing (internal/sequence).
Package idgen composes and parses the generated test-case identifiers that give each test case its stable, human-readable name: strings of the form "RHEL9-AC-02.03-001" - {COMPONENT}-{FAMILY}-{NUMBER}[.{ENHANCEMENT}]-{SEQUENCE} - built from a validated component code (internal/catalog), a resolved control (internal/catalog), and the next sequence number for that component+control pairing (internal/sequence).
migrate
Package migrate implements the pure transformation logic the combined migration tool (issue #39) applies to a single old-format test-case file: reparenting it onto the new ID-keyed path scheme (internal/testcase.NewTestCasePath) and populating its frontmatter's new id field (internal/idgen.GenerateID), in one pass, per file.
Package migrate implements the pure transformation logic the combined migration tool (issue #39) applies to a single old-format test-case file: reparenting it onto the new ID-keyed path scheme (internal/testcase.NewTestCasePath) and populating its frontmatter's new id field (internal/idgen.GenerateID), in one pass, per file.
sequence
Package sequence parses and renders the YAML sequence-counter file that tracks the next available test-case number for each {COMPONENT}-{FAMILY}-{CONTROL}[.{ENHANCEMENT}] key, so IDs generated for the same component+control pairing never collide.
Package sequence parses and renders the YAML sequence-counter file that tracks the next available test-case number for each {COMPONENT}-{FAMILY}-{CONTROL}[.{ENHANCEMENT}] key, so IDs generated for the same component+control pairing never collide.
server
This file establishes the /api/v1 namespace (issue #95): the foundation for a JSON API alongside this app's existing server-rendered HTML/htmx screens (see server.go's own package doc comment).
This file establishes the /api/v1 namespace (issue #95): the foundation for a JSON API alongside this app's existing server-rendered HTML/htmx screens (see server.go's own package doc comment).
testcase
Package testcase parses and renders the YAML frontmatter block and Markdown body of a test-case file.
Package testcase parses and renders the YAML frontmatter block and Markdown body of a test-case file.
validation
Package validation provides centralized validation logic for test case frontmatter, paths, and related data structures.
Package validation provides centralized validation logic for test case frontmatter, paths, and related data structures.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL