signer

package
v0.5.2 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Overview

Package signer opens release and kill-list signing keys by URI (ADR-0038):

file://PATH or PATH   PKCS#8 PEM ed25519 or ECDSA P-256 key (the default; unchanged)
awskms://KEY[?region=R&endpoint=URL&fips=true]
                      AWS KMS asymmetric SIGN_VERIFY key (ECC_NIST_P256 or ECC_NIST_EDWARDS25519)
exec:///ABS/PATH[?arg=A&arg=B&key=ID&timeout=30s]
                      external signer speaking the halos.signer.v1 JSON protocol (exec.go; docs guides/key-management):
                      PKCS#11 HSMs, GCP/Azure KMS, Vault transit, ... without Halos taking their SDKs

Every backend yields a bundle.KeySigner whose algorithm is one halod verifies natively (bundle.AlgEd25519, bundle.AlgECDSAP256). A remote backend's public key is fetched once at Open, and every signature it returns is verified against that key before Halos uses it, so a backend that signs with the wrong key or algorithm fails at signing time, not on the fleet.

Index

Constants

View Source
const (
	ExecProtocol  = "halos.signer.v1"
	ExecEnvPrefix = "HALOS_SIGNER_" // passed through to the signer

)

The external-signer protocol, halos.signer.v1 (guides/key-management in the docs). Halos runs the command (no shell) once per operation, writes one JSON request to its stdin and closes it, and reads one JSON response from stdout. Exit status 0 with a response without "error" is success. stderr is for diagnostics only: Halos logs it at debug level, truncated, and never puts it in an error message. The command gets a minimal environment: PATH (absolute entries only), HOME, every HALOS_SIGNER_* variable, and the variables the URI names with env= (an HSM PIN or token goes there, never in the URI: arguments show in ps). It runs in / (Unix). Its whole process group is killed when it exits, times out or is cancelled. Before every run the binary, its symlink target and every ancestor directory are checked (owner, writability) and, with sha256=, its digest.

-> {"protocol":"halos.signer.v1","op":"public","keyId":"<key param>"}
<- {"protocol":"halos.signer.v1","algorithm":"ecdsa-p256-sha256"|"ed25519","publicKey":"<PKIX PEM>"}

-> {"protocol":"halos.signer.v1","op":"sign","keyId":"...","algorithm":"...",
    "message":"<base64 bytes to sign>","sha256":"<base64 SHA-256 of message>"}
<- {"protocol":"halos.signer.v1","signature":"<base64>"}

<- {"protocol":"halos.signer.v1","error":"<reason>"}   (any op)

ed25519 signs message itself (pure Ed25519); ecdsa-p256-sha256 signs the sha256 digest and answers ASN.1 DER (not raw r||s).

View Source
const DefaultTimeout = 30 * time.Second

DefaultTimeout bounds one remote signing operation (a KMS call or one run of an external signer) when the context has no earlier deadline.

Variables

This section is empty.

Functions

func ExecURI

func ExecURI(p string, q url.Values) string

ExecURI builds the exec:// URI for the signer at the native path p with query q (arg, env, key, sha256, timeout; nil for none): exec:///abs/path on Unix, exec:///C:/path/to/signer.exe for a Windows drive path. Use it rather than concatenating "exec://"+p, which is wrong on Windows.

func Open

func Open(ctx context.Context, uri string, o Options) (bundle.KeySigner, error)

Open returns the signer uri names. A bare path is a file:// URI.

func Scheme

func Scheme(uri string) string

Scheme reports the key URI's backend: "file", "awskms" or "exec".

Types

type Options

type Options struct {
	// HTTPClient is used for awskms (default: DefaultTimeout, no redirects).
	HTTPClient *http.Client
	// Credentials signs awskms requests; nil is the AWS SDK default chain
	// (env, shared config/SSO, web identity/IRSA, ECS/EC2 IMDS).
	Credentials aws.CredentialsProvider
	// Region is the awskms region when neither the URI nor the key ARN names
	// one; "" falls back to the AWS SDK default config.
	Region string
	// Now is the SigV4 clock (tests).
	Now func() time.Time
	// Log receives exec signers' stderr at debug level (nil: slog.Default).
	Log *slog.Logger
}

Options tune remote backends; the zero value is production.

Jump to

Keyboard shortcuts

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