-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Problem
Users connecting to HTTPS endpoints secured with certificates signed by custom or private Certificate Authorities (common in enterprise environments) cannot establish connections because aepcli only trusts system-installed CA certificates.
Current behavior:
$ aepcli myapi resources list
Error: Get "https://api.internal": x509: certificate signed by unknown authorityImpact: Enterprise users cannot connect to internal APIs that use certificates signed by organizational Certificate Authorities.
Motivation
Enterprise and organizational environments frequently use internal Certificate Authorities to sign certificates for internal services. While adding the CA certificate to the system trust store is the standard approach, this is not always practical or possible:
Enterprise environment constraints:
- Developers often lack administrative privileges to modify system trust stores in managed workstations
- Corporate security policies may restrict or prohibit system-level certificate modifications
- Centrally-managed environments require IT approval for trust store changes
Development workflow challenges:
- Containerized development environments don't persist trust store changes between rebuilds
- CI/CD pipelines may not have permissions to modify runner trust stores
- Multi-environment testing (dev, staging, prod) may use different CAs
Cross-platform complexity:
- Trust store locations and modification procedures vary significantly across Windows, macOS, and Linux
- System trust store changes are global and may affect other applications
Developers need a non-privileged, portable way to specify custom CA certificates without requiring system-level changes or administrative approval.
Similar features in other CLI tools:
- kubectl:
--certificate-authority - curl:
--cacert - aws-cli:
--ca-bundle - docker:
--tlscacert - git:
http.sslCAInfo
User Story
As a developer working with internal enterprise APIs,
I want to specify a custom CA certificate via a CLI flag,
So that I can connect to HTTPS endpoints secured by my organization's Certificate Authority without modifying system trust stores.
Proposed Solution
Add a --ca-cert <file> CLI flag that:
- Accepts a path to a PEM-encoded CA certificate file
- Adds the certificate to the trusted CA pool (additive to system CAs)
- Does not replace or remove system CA certificates
- Validates the certificate file format before use
- Provides clear error messages for invalid or missing files
Key principle: Custom CA certificates should be added to the system CA pool, not replace it. This ensures connections to public HTTPS endpoints (e.g., github.com) continue to work normally.
Expected Behavior
Without flag (default - only system CAs trusted):
$ aepcli myapi resources list
Error: Get "https://api.internal": x509: certificate signed by unknown authorityWith flag (custom CA added to trust pool):
$ aepcli --ca-cert /etc/ssl/certs/corporate-ca.pem myapi resources list
{
"resources": [...]
}With flag pointing to non-existent file:
$ aepcli --ca-cert /path/does-not-exist.pem myapi resources list
Error: Failed to read CA certificate from /path/does-not-exist.pem: file does not exist
To fix this issue:
1. Verify the file path is correct
2. Ensure the file exists and is readable
3. Verify the file contains a valid PEM-encoded certificate
Use 'openssl x509 -in /path/to/ca.pem -text -noout' to verify the certificate.With flag pointing to invalid PEM file:
$ aepcli --ca-cert /path/invalid.pem myapi resources list
Error: Failed to parse CA certificate from /path/invalid.pem: not valid PEM format
Expected PEM format:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Use 'openssl x509 -in /path/to/ca.pem -text -noout' to verify the certificate.Combined with other flags:
$ aepcli --ca-cert /etc/ssl/corporate-ca.pem --log-http myapi resources create foo --name="test"
Request: POST https://api.internal/resources
...Public HTTPS endpoints still work:
# System CAs are preserved, so public endpoints work normally
$ aepcli --ca-cert /etc/ssl/corporate-ca.pem github-api repos list
# Successfully connects using public CA (DigiCert, Let's Encrypt, etc.)Acceptance Criteria
-
--ca-cert <file>flag is available as a persistent flag - Flag accepts a file path to a PEM-encoded certificate
- Custom CA certificate is added to system CA pool (not replaced)
- System CA certificates continue to work (connections to public HTTPS endpoints succeed)
- Validates certificate file exists before attempting to load
- Validates PEM format and provides clear error for invalid files
- Provides helpful error messages with remediation steps
- Connections to endpoints using custom CA succeed
- Connections to endpoints using public CAs continue to work
- Debug logging shows when custom CA is loaded (when
--log-level=debug) - Flag can be combined with all other existing flags
- Unit tests validate certificate loading and validation
- Integration tests verify connections with custom CA certificates
- Documentation includes usage examples and troubleshooting guide
Certificate File Format
The flag must accept standard PEM-encoded X.509 certificates:
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKL0UG+mRkSvMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
...
-----END CERTIFICATE-----
Supported formats:
- Single certificate per file
- PEM encoding (Base64 with
-----BEGIN CERTIFICATE-----header)
Not supported in this issue (future enhancements):
- Multiple certificates in one file (certificate chains)
- DER-encoded certificates
- PKCS#7 or PKCS#12 formats
- Certificate directories
Error Messages
All error messages should be actionable and guide users to resolution:
Missing file:
Error: Failed to read CA certificate from <path>: file does not exist
To fix this issue:
1. Verify the file path is correct
2. Ensure the file exists and is readable
Invalid PEM format:
Error: Failed to parse CA certificate from <path>: not valid PEM format
Expected format:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Use 'openssl x509 -in <path> -text -noout' to verify the certificate.
Permission denied:
Error: Failed to read CA certificate from <path>: permission denied
To fix this issue:
1. Verify you have read permissions for the file
2. Check file permissions with: ls -l <path>
Debug Logging
When --log-level=debug is set, log certificate loading:
$ aepcli --log-level=debug --ca-cert /etc/ssl/corporate-ca.pem myapi resources list
DEBUG: Loading TLS configuration
DEBUG: System CA certificates loaded from system trust store
DEBUG: Custom CA certificate loaded from /etc/ssl/corporate-ca.pem
DEBUG: Connecting to https://api.internal
...Out of Scope
The following are explicitly out of scope for this issue and will be addressed separately:
- Environment variable support (e.g.,
AEPCLI_CA_CERT,SSL_CERT_FILE) - Configuration file support (per-API or global CA certs)
- Multiple
--ca-certflags (loading multiple CA certificates) - Certificate directories (e.g.,
--ca-cert-dir) - Certificate chains or intermediate certificates
- Client certificate authentication (mTLS)
- Certificate pinning
- TLS version or cipher configuration
Security Considerations
This feature improves security by enabling proper certificate verification:
-
Additive trust model: Custom CA certificates are added to the system CA pool, not replacing it. This ensures:
- Public HTTPS endpoints continue to work normally
- Standard security practices are preserved
- No reduction in security for public endpoints
-
Certificate validation: Files are validated before use to prevent confusing errors later in the TLS handshake
-
No privilege escalation: Does not require administrative privileges or system modifications
-
User responsibility: Users are responsible for:
- Securing their CA certificate files (recommended:
chmod 644orchmod 600) - Verifying they trust the CA certificate being added
- Understanding the security implications of trusting a custom CA
- Securing their CA certificate files (recommended:
-
Transparency: Debug logging shows which certificates are loaded for troubleshooting
Related Issues
- #TBD - Add environment variable support for CA certificates (
AEPCLI_CA_CERT,SSL_CERT_FILE) - #TBD - Add config file support for CA certificates
- #TBD - Add support for multiple CA certificates
- #TBD - Add support for CA certificate directories
References
- kubectl --certificate-authority
- curl --cacert
- AWS CLI ca-bundle
- Go crypto/tls package
- Go crypto/x509 package
- OpenSSL x509 command
Additional Context
This is the proper, secure solution for connecting to endpoints with custom Certificate Authorities. Unlike --insecure-skip-tls-verify (which disables security), this feature maintains full certificate verification while trusting additional CAs.
This is the first step in a series of CA certificate support enhancements. Future improvements will add:
- Environment variable support (for CI/CD and containerized workflows)
- Config file support (for persistent per-API configuration)
- Multiple certificate support (for complex CA hierarchies)
- Certificate directory support (for managing many CA certificates)