larksuite/cli · error
unsafe %s %q: %w
Error message
unsafe %s %q: %w
What it means
The extra root CA file (CLI_CA_PATH) passed binding.AssertSecurePath: it is absolute but unsafe — e.g. permissions too open in the wrong direction, symlink issues, or located in a disallowed location. The CLI wraps the underlying security-audit error with 'unsafe %s %q: %w' and refuses to load the CA.
Source
Thrown at internal/transport/tls_ca.go:35
)
// applyExtraRootCA augments t with an additional PEM bundle used for configured proxy
// TLS interception.
func applyExtraRootCA(t *http.Transport, caPath string) error {
caPath = strings.TrimSpace(caPath)
if caPath == "" {
return nil
}
if !filepath.IsAbs(caPath) {
return fmt.Errorf("invalid %s %q: must be an absolute path to a PEM file", envvars.CliCAPath, caPath)
}
safeCAPath, err := binding.AssertSecurePath(binding.AuditParams{
TargetPath: caPath,
Label: envvars.CliCAPath,
AllowReadableByOthers: true,
})
if err != nil {
return fmt.Errorf("unsafe %s %q: %w", envvars.CliCAPath, caPath, err)
}
pemBytes, err := vfs.ReadFile(safeCAPath)
if err != nil {
return fmt.Errorf("failed to read %s %q: %w", envvars.CliCAPath, caPath, err)
}
// Augment the system trust store. Do NOT silently discard a SystemCertPool
// error: falling back to an empty pool would make this transport trust ONLY
// the extra CA (dropping all system roots), which narrows trust unexpectedly
// and could break TLS to legitimate endpoints. Fail closed instead.
pool, err := x509.SystemCertPool()
if err != nil {
return fmt.Errorf("failed to load system cert pool for %s: %w", envvars.CliCAPath, err)
}
if pool == nil {
pool = x509.NewCertPool()
}
if ok := pool.AppendCertsFromPEM(pemBytes); !ok {View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Inspect the wrapped cause (%w) to see which security check failed.
- Move the CA file to a dedicated root-owned directory such as /etc/lark-cli/ with 0644 perms and no symlinks.
- Re-run with the new absolute path in CLI_CA_PATH.
Defensive patterns
Strategy: validation
Validate before calling
fi, err := os.Lstat(caPath)
if err != nil || fi.Mode()&os.ModeSymlink != 0 {
return fmt.Errorf("CA path must be a regular, non-symlinked file")
} Try / catch
if err := applyExtraRootCA(tr, caPath); err != nil {
var secErr *binding.SecurityError
if errors.As(err, &secErr) {
log.Fatalf("CA path rejected by security policy: %v", secErr)
}
return err
} Prevention
- Keep the CA file in a root-owned directory with no symlinks.
- Check the wrapped cause for which security rule tripped.
- Provision the file with install -m 0644 from a trusted source.
When it happens
Trigger: CLI_CA_PATH points to a file that fails AssertSecurePath — symlinked path, path under a world-writable directory, or other policy violation — while AllowReadableByOthers is requested; raised in ApplyToTransport -> applyExtraRootCA.
Common situations: CA bundle placed in /tmp or another shared directory; symlink chains created for convenience; hardened environments where file ownership is root but the CLI runs unprivileged.
Related errors
- %s: path must be absolute, got %q
- %s: cannot stat %q: %w
- %s: path %q is a directory, not a file
- %s: path %q is a symlink (not allowed)
- exec provider security audit failed: %w
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/488f7ef6c0e68192.
Report an issue: GitHub.