docs(openssl): operator playbook for shell-out threat model

Closes Top-10 fix #6 of the 2026-05-03 issuer-coverage audit (see
cowork/issuer-coverage-audit-2026-05-03/RESULTS.md). Pre-fix, the
OpenSSL adapter's docs in docs/connectors.md explained usage but
did NOT enumerate the threat model. The adapter exec's an arbitrary
operator-supplied script — env-var inheritance, symlink attacks,
sandbox-escape, multi-tenant process-isolation gaps. An acquirer's
security reviewer reading this surface cold pattern-matches
"highest-risk issuer surface with the lowest documented threat
model."

This commit lands a doc-side operator playbook in
docs/connectors.md OpenSSL section (mirrors Bundle 8's "Operator
playbook: keytool argv password exposure" subsection shape and
the 2026-05-02 audit Top-10 fix #7 SSH InsecureIgnoreHostKey
playbook). Six topics covered:

  1. Why the adapter exists despite the risk (CLI-driven CAs
     without Go SDKs need an integration path).
  2. Threat model the adapter accepts (trusted operator + trusted
     script + appropriate ownership + clear audit trail).
  3. Threat model the adapter does NOT accept (operator-writable
     script paths, untrusted content, multi-tenant hosts).
  4. Mitigations operators can layer (dedicated user, root-owned
     0755 binary, audit rules, per-call timeout via
     CERTCTL_OPENSSL_TIMEOUT_SECONDS, env sanitisation,
     chroot/container, audit wrapper, per-call concurrency
     bound).
  5. When NOT to use the adapter (compliance environments,
     multi-tenant servers, no-script-review environments).
  6. V3-Pro forward path (hardened mode tracked in
     cowork/WORKSPACE-ROADMAP.md).

Inline comment in internal/connector/issuer/openssl/openssl.go
near the callSignScript exec call site forward-references the
new doc subsection (no logic change).

cowork/WORKSPACE-ROADMAP.md gains an "OpenSSL hardened mode" V3-
Pro entry under "Adapter hardening" — sibling-folder doc, not in
the certctl repo, so not reflected in this commit's diff.

Same shape Bundle 8 used for the JavaKeystore playbook and the
2026-05-02 deployment-target audit Top-10 fix #7 used for the SSH
InsecureIgnoreHostKey playbook.

No code logic changes (only the explanatory comment near the
exec call site). No test changes. Doc-only commit.

Verified locally:
- gofmt / go vet clean.
- go test -short -count=1 ./internal/connector/issuer/openssl/...
  green.

Audit reference: cowork/issuer-coverage-audit-2026-05-03/RESULTS.md
Top-10 fix #6.
This commit is contained in:
shankar0123
2026-05-03 21:28:05 +00:00
parent 0792271dc6
commit 869fc8f245
2 changed files with 57 additions and 1 deletions
+14 -1
View File
@@ -443,13 +443,26 @@ func (c *Connector) writeTempFile(data []byte, prefix string) (string, error) {
// callSignScript calls the sign script with CSR and cert output file paths.
// Returns the script's error message if execution fails.
//
// Threat model: the OpenSSL adapter execs an operator-supplied
// script for every certificate lifecycle operation. The script
// runs as the certctl-server user with full filesystem and
// network access. See "Operator playbook: OpenSSL shell-out
// threat model" in docs/connectors.md (OpenSSL section) for the
// threat model accepted, threat model rejected, mitigations
// operators can layer (dedicated user, root-owned 0755 binary,
// audit rules, per-call timeout via CERTCTL_OPENSSL_TIMEOUT_SECONDS,
// env sanitisation, chroot/container), and when not to use this
// adapter (compliance environments, multi-tenant servers,
// no-script-review environments). Top-10 fix #6 of the 2026-05-03
// issuer-coverage audit.
func (c *Connector) callSignScript(ctx context.Context, csrFile, certFile string) error {
ctx, cancel := context.WithTimeout(ctx, c.timeout)
defer cancel()
// Call sign script: <sign_script> <csr_file> <cert_output_file>
cmd := exec.CommandContext(ctx, c.config.SignScript, csrFile, certFile)
cmd.Env = os.Environ() // Inherit environment
cmd.Env = os.Environ() // Inherit environment — see threat-model doc above.
output, err := cmd.CombinedOutput()
if err != nil {