Public Key Embedding
The license server uses Ed25519 public key cryptography to validate server licenses. The public key can be embedded at build time for easier deployment, or loaded from a file at runtime.
Why Embed?
Section titled “Why Embed?”Embedding the public key at build time has several advantages:
- Simpler deployment — no need to distribute the
license.pubfile separately. - Reduced configuration — the server works out of the box without additional setup.
- Better security — the key is baked into the binary, reducing the attack surface.
How It Works
Section titled “How It Works”-
Generate a key pair (developer/CI only):
Terminal window ./license-tool generate-keys# Creates: license.key (private) and license.pub (public) -
Build with the embedded key using one of the methods below.
-
At runtime, the server checks the
EmbeddedPublicKeyvariable first. If it is set, no file loading is needed. If it is empty, the server falls back to loading from disk.
Build Configuration
Section titled “Build Configuration”Makefile
Section titled “Makefile”The Makefile automatically reads license.pub and embeds it:
PUBLIC_KEY_FILE?=license.pubPUBLIC_KEY_EMBEDDED=$(shell cat "$(PUBLIC_KEY_FILE)" | base64 -w0)LDFLAGS=-ldflags "-X 'git.prd.embidio.de/hive/license-server/internal/license.EmbeddedPublicKey=$(PUBLIC_KEY_EMBEDDED)'"Build the server:
make build-server# Automatically embeds license.pub if presentGoReleaser
Section titled “GoReleaser”GoReleaser uses the PUBLIC_KEY_EMBEDDED environment variable:
before: hooks: - test -f license.pub || echo "WARNING: license.pub not found"
builds: - ldflags: - -X 'git.prd.embidio.de/hive/license-server/internal/license.EmbeddedPublicKey={{ .Env.PUBLIC_KEY_EMBEDDED }}'# Set environment variableexport PUBLIC_KEY_EMBEDDED=$(cat license.pub | base64 -w0)
# Build releasegoreleaser release --cleanManual Go Build
Section titled “Manual Go Build”PUBLIC_KEY=$(cat license.pub | base64 -w0)go build -ldflags="-X 'git.prd.embidio.de/hive/license-server/internal/license.EmbeddedPublicKey=$PUBLIC_KEY'" ./cmd/serverRuntime File Loading (Fallback)
Section titled “Runtime File Loading (Fallback)”If no key is embedded at build time, the server looks for license.pub at runtime in these locations, in order:
./license.pub(current working directory)./configs/license.pub/etc/license-server/license.pub
Code Structure
Section titled “Code Structure”The embedding relies on two components:
internal/license/server_license.go:
// EmbeddedPublicKey contains the Ed25519 public key embedded at build time.var EmbeddedPublicKey stringinternal/config/config.go:
func (c *Config) loadPublicKey() error { // 1. Try embedded public key first if license.EmbeddedPublicKey != "" { c.ServerLicensePublicKey = []byte(license.EmbeddedPublicKey) return nil }
// 2. Fall back to file loading // ...}Key Format
Section titled “Key Format”The public key is stored in PEM format:
-----BEGIN ED25519 PUBLIC KEY-----MCowBQYDK2VwAyEA... (base64 encoded bytes)-----END ED25519 PUBLIC KEY-----At build time, the entire PEM block is base64-encoded again for embedding as a string constant via -ldflags.
Security Considerations
Section titled “Security Considerations”Private Key (license.key)
Section titled “Private Key (license.key)”- NEVER commit to version control.
- NEVER embed in binaries.
- Store securely (HSM, secrets manager, encrypted storage).
- Used only for signing server licenses.
- Keep on developer/CI machine only.
Public Key (license.pub)
Section titled “Public Key (license.pub)”- Safe to embed in binaries.
- Safe to commit to version control (if desired).
- Used only for verification (read-only operation).
- Cannot be used to create licenses.
Workflows
Section titled “Workflows”Developer / Release Manager
Section titled “Developer / Release Manager”# One-time: Generate key pair./license-tool generate-keys# Keep license.key secure!# license.pub will be embedded in builds
# Build with embedded keymake build-release
# Create server license (using private key)./license-tool create \ --licensee "Customer Company" \ --valid-days 365 \ --private-key license.key \ --output server.licenseCustomer Deployment
Section titled “Customer Deployment”# Extract release packagetar -xzf license-server_v1.0.0_linux_amd64.tar.gz
# Copy configurationcp config.example.yaml config.yaml
# Edit config.yaml to set server license# license:# server_license: "<base64-encoded-license>"
# Start server (public key is already embedded!)./license-server serveVerification
Section titled “Verification”To check if a binary has an embedded public key:
# Extract embedded strings (Linux)strings license-server | grep "BEGIN ED25519 PUBLIC KEY"
# Or check at runtime./license-server version --verboseTroubleshooting
Section titled “Troubleshooting””public key not found” error
Section titled “”public key not found” error”If the key IS embedded:
This should not happen. Check build logs and verify that the -ldflags value was set correctly.
If the key is NOT embedded:
Place license.pub in one of the fallback locations:
cp license.pub ./# ORcp license.pub ./configs/# ORsudo cp license.pub /etc/license-server/Building without embedding
Section titled “Building without embedding”If you want to build without embedding the key (for testing):
# Temporarily rename/remove license.pubmv license.pub license.pub.bakmake build-servermv license.pub.bak license.pub