Allow-list a JAR Executable
For security reasons, you should define an allow-list
of which JAR executables VaultCode will accept and execute.
This can be done via a code signing certificates or via JAR hashes.
Allowlisting JARs allows the HSM operator to restrict which JARs can be loaded to VaultCode.
Allowlisting is done using the configuration options in the application.yml.
Operators can limit the maximum size of a JAR via the vaultcode.maxExecutableSize setting.
VaultCode enforces that this setting is set to 500 MB or less.
Example Use Case
While developing locally, each developer can have their own JKS, that they do not share with other developers, similar to their own private keys. In CI/CD pipelines, the pipeline can have its own code signing certificate to build and deploy your JARs to a test environment.
Lastly, once you are in production, the code signing key should be strictly protected and access to it should be limited. For example, only Release Managers may access to the signing key, and the key is stored inside an HSM. The signing key could also be an SKA key, to enforce that multiple Release Managers need to approve a release.
Alternatively, you could allowlist JAR fingerprints, to enforce explicit and intentional upgrade ceremonies.
This works because uploading a new, edited application.yml to VaultContainers requires Security Officer (SO) intervention,
and SO privileges are usually protected with 2-of-n.
Allowlist Code Signing Certificates
To streamline the development process while maintaining security, you can use code signing certificates. Multiple certificates can be onboarded to allow changes from different developers who each have their own code signing key.
-
Create a code signing key pair per environment or developer.
export ALIAS="vaultcode_developer_1"
keytool -genkeypair \
-alias "$ALIAS" \
-keyalg "EC" \
-groupname "secp256r1" \
-validity "365" \
-keystore "vaultcode_keystore.jks" \
-storepass "changeme" \
-keypass "changeme" \
-dname "CN=Developer Name VaultCode, OU=IT, O=Company, L=Zurich, ST=Zurich, C=CH" -
Extract and print the certificate:
keytool -exportcert -alias "$ALIAS" -storepass "changeme" -keystore vaultcode_keystore.jks -rfc -file "$ALIAS.pem"You can inspect the certificate with OpenSSL:
openssl x509 -in vaultcode_developer_1.pem -text -noout -
Allow-list the signing certificate in the VaultCode configuration.
The
vaultcode.allowlistUploadExecutable.jarSignerCertificatescontains a list of strings. Every string should either be the raw certificate or a path to the certificate file, prefixed withfile:. If you use a file, you need to mount this file as a volume to the VaultCode Docker container.vaultcode:
allowlistUploadExecutable:
jarSignerCertificates:
# Specify certificate as inline PEM.
- |
-----BEGIN CERTIFICATE-----
MIIB+zCCAaCgAwIBAgIJAPsGPWYvOQP3MAoGCCqGSM49BAMDMHExCzAJBgNVBAYT
AkNIMQ8wDQYDVQQIEwZadXJpY2gxDzANBgNVBAcTBlp1cmljaDEQMA4GA1UEChMH
Q29tcGFueTELMAkGA1UECxMCSVQxITAfBgNVBAMTGERldmVsb3BlciBOYW1lIFZh
dWx0Q29kZTAeFw0yNjAzMDQxMDMxNDlaFw0yNzAzMDQxMDMxNDlaMHExCzAJBgNV
BAYTAkNIMQ8wDQYDVQQIEwZadXJpY2gxDzANBgNVBAcTBlp1cmljaDEQMA4GA1UE
ChMHQ29tcGFueTELMAkGA1UECxMCSVQxITAfBgNVBAMTGERldmVsb3BlciBOYW1l
IFZhdWx0Q29kZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHCj6RmP/5489zSE
qZDRoy+Ep9uvDs7DkTptBSSCElU9XiMtdk2y3G90ZzZ2gATmG6jjYXdPEt5EEaFF
zTeJRqqjITAfMB0GA1UdDgQWBBRvo+LpeOWvqbosgg1VcCheZJAUojAKBggqhkjO
PQQDAwNJADBGAiEAtxi3Z/Ee2VZEU8yWR3Zz9fGfhMfT3ifJBaFU2OThh4ECIQD8
NKpoGLApmfyBjJI3D4PzLwZEYwB/NdFZJcFO9g9jQg==
-----END CERTIFICATE-----
# Specify a file that is mounted as a Docker volume.
- "file:/app/vault-code/jar-signers/developer1.crt"infoWhen running VaultCode inside the HSM, you must specify the certificates directly inside the YAML. This is because in VaultContainers, you cannot mount custom volumes.
-
Compile your code into a JAR.
-
Sign your JAR.
jarsigner -keystore vaultcode_keystore.jks -storepass changeme -keypass changeme -signedjar signed.jar unsigned.jar "$ALIAS" -
Verify the JAR signature (as a sanity check).
jarsigner -verify -keystore vaultcode_keystore.jks -storepass changeme signed.jar
The Primus Tools
offer a drop-in replacement for keytool and jarsigner.
This allows you to keep your signing keys securely on a Primus HSM instead of in a local file.
Allowlist Executable Hashes
The configuration file for VaultCode has the option vaultcode.allowlistUploadExecutable.fingerprints.
This option should be a list of strings (or an empty list).
Every string is the hash of the JAR to be allowlisted, prefixed by the hash algorithm.
vaultcode:
allowlistUploadExecutable:
fingerprints:
- "sha256:e7fd9dec16945df11753dfcac5f2993bac870991868d2ea59ee957e7f3053ad3"
- "sha1:109f765261e3a64c639d42103e32c4e6f0333d9a"
To get the fingerprint (hash) of a JAR, run:
sha256sum PositiveApprovalExecutable.jar
Multiple fingerprints can be listed to allow JARs to be swapped out dynamically.
Note that at runtime, clients still need to call the /api/v1/upload_execution_code endpoint
to upload (and thus change to) another JAR.
The benefit is that SOs can allow-list all JARs once ahead of time.
Verify Your Configuration
To verify that the access control is working, upload a JAR file:
JAR=/path/to/code.jar
curl "https://demo-vaultcode.securosys.com/api/v1/upload_execution_code" --form "file=@${JAR};type=application/java-archive"
If you attempt to upload a JAR that is unsigned or whose fingerprint is not allowlisted, the response will contain one of the following errors:
{"errorCode":414,"reason":"res.error.invalid.fingerprint","message":"Provided JAR file not match fingerprint in YAML"}
{"errorCode":459,"reason":"res.error.validate.jar.signature","message":"No signer certificate found in JAR"}
{"errorCode":460,"reason":"res.error.validation.certificate.fingerprint","message":"Signer certificate does not match expected certificate"}
Which Option to Use
You have four options:
- Define nothing.
- In this case VaultCode allows uploading any JAR.
- Allowlist only fingerprints.
- Allowlist only certificates.
- Allowlist both fingerprints and certificates.
- In this case, any uploaded JAR must match both a configured fingerprint and be signed by one of the JAR signer certificates.
Both approaches have benefits and downsides. Below is an overview of what to consider when deciding which option is best for your use case.
| Certificate | Fingerprint | |
|---|---|---|
| Pros |
|
|
| Cons |
|
|