There are several reasons to store certain types of files such as secrets, certificates, private keys, etc. But without exaggerating, Vault is not a file store.
One of the simplest ways is to actually use KV for this, but I will show you in a simple way how to store the certificate we use here in our project as a simple file in the vault.
To do this, I will create a structure in Vault “secret/data/infrastructure/certificates/*” for all certificates, I will create a policy and assign it to our approle jenkins-role (See other Vault posts).
Just be aware that you don’t add permissions to an app-role token, etc. You need to recreate it, so be careful with the token values, or create another app-role.
Some files, due to their non-text content, may be better converted to Base64 before importing into Vault, although the example is only with a text file with the certificate, I will show how to do it with Base64 as well.
First, we have to have our certificate in hand:
ldapserver-cert.crt
----BEGIN CERTIFICATE-----
MIIFwjCCA6qgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwgYQxCzAJBgNVBAYTAlBU
MQ4wDAYDVQQIDAVQb3J0bzEOMAwGA1UEBwwFUG9ydG8xEjAQBgNVBAoMCURldm9w
cy1EQjEcMBoGA1UEAwwTbGRhcC5kZXZvcHMtZGIuaW5mbzEjMCEGCSqGSIb3DQEJ
ARYUYWRtaW5AZGV2b3BzLWRiLmluZm8wHhcNMjQwNDA4MTEzMzE0WhcNMjUwNDA4
MTEzMzE0WjB0MQswCQYDVQQGEwJQVDEOMAwGA1UECAwFUG9ydG8xEjAQBgNVBAoM
CURldm9wcy1EQjEcMBoGA1UEAwwTbGRhcC5kZXZvcHMtZGIuaW5mbzEjMCEGCSqG
SIb3DQEJARYUYWRtaW5AZGV2b3BzLWRiLmluZm8wggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQCz6rcxPNUdN37jfFmMf/Mwdxmf6ST3hulCJAxNBBHzOSOW
+umvVhfqtw88X3dgq3CW7fQvGQ2izqzN/2MLSe7yV9I1LGqLmtwN2IHTTpC3NAeH
8qlfuwHi+IvO2eFr0EGaL4rT5O+h8qnthPWI1/Rh9xdkx9xvTvVTsElkNZJ+zAZs
E41XwWRsxwHUyDRxQIL2EGbUVyjbJgTzoxQQHdetIeYc6Vya7ABHa6iwfSMKR99A
NdOujpnNecGnGJSzQ0B6RXp2ae28LjjyVdMV1wo6PrvgsKqt5MO4GxyPKginVp0s
ly2zVshCzREw6/4lxxJXqRHcmcS6mhm0U77QTG32A2bU+SJONqxF6GVil60sGm59
MxwDvkgQuE9QDQ4+txYh8K97PfxqVcPG92PS2sYOinc1EBsnD6TEsuvfc8m0Ev3m
njZ+jgJA4Gf+e9AbfgQVJEbdQj7mM2gRFL7CWKAgzk2KRh9xWTlk8nCwqCwHx57d
hE+qfC/SkInZCQHGTSQ22+RidEXq7GxtY2KDNSFSTPeGjR8KA5+lqeuIf8ZeHc6s
HEtK12B8yvYDfRyCBnPugXxs77CiTcmUvWCfBP9GZv4icoCdDTzfnfTNaGO9X16+
XY5sC27o24WsxXLF9EDtp6FpnGX1moR6h89Jky+clCwpDUj4sucWz4WPtHpAnwID
AQABo00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBTP5qF7BCcepDXMDBBq+Bbonlr2
FzAfBgNVHSMEGDAWgBRN6D0ZxNB2qFyd9JTxZ/oYSBfMTjANBgkqhkiG9w0BAQsF
AAOCAgEAjz2Hx2s8A+liNwaEGPS1B/TDHDUKgzsrjXPEVfni3vhlhqgczej/rDAX
d8pLJ4QawlFPbQVZqFFsyJjo6dAG2WfIJeA0c+7kw1pVcbVqQKymq7UtOaHiZF8j
jkBuxKJH4P+lxBLSWCiktvqhTJ/1IgQ66R3wve8J0+KCHGsX2BFMA8Zqc48PTXnu
NGLUsIIYNwMlsCyfEYRY9s6Lg5q8Vcb1dN39uJwMe+Q8XKM0tPM+Dn1z4289q9CZ
poGfhonu3u/9e/LsrptE0ZURGqBFCXXU8gAq0Yg1ViGwcA8e6HC6iia6H0Y4vS6j
q33VIswn0In56zw4gOD/BnYHU5B/277hY8UIsU6vQaTZbpE/GpW8RT85V4MT6r5W
MI2WF8ZATyBbJ5PbXctYfmnydQwTXpoNnioGmxH4Qu0S+ydc+yneAIlZWURlq5gB
YuZrmI7xuGxs5UfzQBEFroRlI6QmW95ebkac5XwURTW1/bI5deJZnfTOezRJKr5n
L1yySSIs2rYXQkphDwV6HqSNg3eJSEGusCbV9Kgx52X5uorfot5i1bZUJcSKJJby
38UpFzQ4/SOBewNfWAq6Q1NBWUbfn8BARv96L7n3uK4JrxfkUrHGjzWGJmtlgx+b
shJhA/b/35i7KxmdI6eGy0I3vylbGjaH0WGS4+QRYeJKWXPm6kk=
-----END CERTIFICATE-----
Don’t forget that you need to be logged in with a user that has permissions to configure the approle and create a Secret KV.
Now let’s create the Policy for the structure “secret/data/infrastructure/certificates/*” and recreate the Jenkins approle.
vault policy write infrastructure_certificates -<<EOF
path "secret/data/infrastructure/certificates/*" {
capabilities = [ "read" ]
}
EOF
Success! Uploaded policy: infrastructure_certificates
Now the normal process of configuring an approle, but then adding the newly created infrastructure_certificates to the already used jenkins policy.
$ vault write auth/approle/role/jenkins-role token_num_uses=0 secret_id_num_uses=0 policies=jenkins,infrastructure_certificates
Success! Data written to: auth/approle/role/jenkins-role
$ vault read auth/approle/role/jenkins-role/role-id
Key Value
--- -----
role_id 166b7809-2fc6-1825-7620-f2dff60bcbb1
$ vault write -f auth/approle/role/jenkins-role/secret-id
Key Value
--- -----
secret_id 35e926e7-159e-7df8-36df-35a8289cc418
secret_id_accessor 7be98a44-6771-fa56-27b2-b76645180584
secret_id_num_uses 0
secret_id_ttl 0s
#######################################################################################################################
$ vault write auth/approle/login role_id=166b7809-2fc6-1825-7620-f2dff60bcbb1 secret_id=35e926e7-159e-7df8-36df-35a8289cc418
Key Value
--- -----
token hvs.CAESIAZoY7ZYdHNIJgXIEEUJyG2H2p8w6XrvL4MLW_K4kqUPGh4KHGh2cy5ZREk5Y2YycWIxQkpDcTJLdnBLSkwzSlA
token_accessor PvCw8bJgCjJlT95Qg8DkIsVI
token_duration 768h
token_renewable true
token_policies ["default" "infrastructure_certificates" "jenkins"]
identity_policies []
policies ["default" "infrastructure_certificates" "jenkins"]
token_meta_role_name jenkins-role
One way to upload a file to the Vault is to use “@” before the full file path:
vault kv put secret/infrastructure/certificates/devops-db certificate=@/work/vault/cert/ldapserver-cert.crt
================== Secret Path ==================
secret/data/infrastructure/certificates/devops-db
======= Metadata =======
Key Value
--- -----
created_time 2025-03-12T11:02:18.44676192Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 2
It’s that simple, now let’s log in with the approle we configured and read it.
vault login hvs.CAESIAZoY7ZYdHNIJgXIEEUJyG2H2p8w6XrvL4MLW_K4kqUPGh4KHGh2cy5ZREk5Y2YycWIxQkpDcTJLdnBLSkwzSlA
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
Key Value
--- -----
token hvs.CAESIAZoY7ZYdHNIJgXIEEUJyG2H2p8w6XrvL4MLW_K4kqUPGh4KHGh2cy5ZREk5Y2YycWIxQkpDcTJLdnBLSkwzSlA
token_accessor PvCw8bJgCjJlT95Qg8DkIsVI
token_duration 767h59m38s
token_renewable true
token_policies ["default" "infrastructure_certificates" "jenkins"]
identity_policies []
policies ["default" "infrastructure_certificates" "jenkins"]
token_meta_role_name jenkins-role
For us, at this moment, only the content of the certificate field that we created when we recorded the KV matters.
vault kv get -field=certificate secret/infrastructure/certificates/devops-db
----BEGIN CERTIFICATE-----
MIIFwjCCA6qgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwgYQxCzAJBgNVBAYTAlBU
MQ4wDAYDVQQIDAVQb3J0bzEOMAwGA1UEBwwFUG9ydG8xEjAQBgNVBAoMCURldm9w
cy1EQjEcMBoGA1UEAwwTbGRhcC5kZXZvcHMtZGIuaW5mbzEjMCEGCSqGSIb3DQEJ
ARYUYWRtaW5AZGV2b3BzLWRiLmluZm8wHhcNMjQwNDA4MTEzMzE0WhcNMjUwNDA4
MTEzMzE0WjB0MQswCQYDVQQGEwJQVDEOMAwGA1UECAwFUG9ydG8xEjAQBgNVBAoM
CURldm9wcy1EQjEcMBoGA1UEAwwTbGRhcC5kZXZvcHMtZGIuaW5mbzEjMCEGCSqG
SIb3DQEJARYUYWRtaW5AZGV2b3BzLWRiLmluZm8wggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQCz6rcxPNUdN37jfFmMf/Mwdxmf6ST3hulCJAxNBBHzOSOW
+umvVhfqtw88X3dgq3CW7fQvGQ2izqzN/2MLSe7yV9I1LGqLmtwN2IHTTpC3NAeH
8qlfuwHi+IvO2eFr0EGaL4rT5O+h8qnthPWI1/Rh9xdkx9xvTvVTsElkNZJ+zAZs
E41XwWRsxwHUyDRxQIL2EGbUVyjbJgTzoxQQHdetIeYc6Vya7ABHa6iwfSMKR99A
NdOujpnNecGnGJSzQ0B6RXp2ae28LjjyVdMV1wo6PrvgsKqt5MO4GxyPKginVp0s
ly2zVshCzREw6/4lxxJXqRHcmcS6mhm0U77QTG32A2bU+SJONqxF6GVil60sGm59
MxwDvkgQuE9QDQ4+txYh8K97PfxqVcPG92PS2sYOinc1EBsnD6TEsuvfc8m0Ev3m
njZ+jgJA4Gf+e9AbfgQVJEbdQj7mM2gRFL7CWKAgzk2KRh9xWTlk8nCwqCwHx57d
hE+qfC/SkInZCQHGTSQ22+RidEXq7GxtY2KDNSFSTPeGjR8KA5+lqeuIf8ZeHc6s
HEtK12B8yvYDfRyCBnPugXxs77CiTcmUvWCfBP9GZv4icoCdDTzfnfTNaGO9X16+
XY5sC27o24WsxXLF9EDtp6FpnGX1moR6h89Jky+clCwpDUj4sucWz4WPtHpAnwID
AQABo00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBTP5qF7BCcepDXMDBBq+Bbonlr2
FzAfBgNVHSMEGDAWgBRN6D0ZxNB2qFyd9JTxZ/oYSBfMTjANBgkqhkiG9w0BAQsF
AAOCAgEAjz2Hx2s8A+liNwaEGPS1B/TDHDUKgzsrjXPEVfni3vhlhqgczej/rDAX
d8pLJ4QawlFPbQVZqFFsyJjo6dAG2WfIJeA0c+7kw1pVcbVqQKymq7UtOaHiZF8j
jkBuxKJH4P+lxBLSWCiktvqhTJ/1IgQ66R3wve8J0+KCHGsX2BFMA8Zqc48PTXnu
NGLUsIIYNwMlsCyfEYRY9s6Lg5q8Vcb1dN39uJwMe+Q8XKM0tPM+Dn1z4289q9CZ
poGfhonu3u/9e/LsrptE0ZURGqBFCXXU8gAq0Yg1ViGwcA8e6HC6iia6H0Y4vS6j
q33VIswn0In56zw4gOD/BnYHU5B/277hY8UIsU6vQaTZbpE/GpW8RT85V4MT6r5W
MI2WF8ZATyBbJ5PbXctYfmnydQwTXpoNnioGmxH4Qu0S+ydc+yneAIlZWURlq5gB
YuZrmI7xuGxs5UfzQBEFroRlI6QmW95ebkac5XwURTW1/bI5deJZnfTOezRJKr5n
L1yySSIs2rYXQkphDwV6HqSNg3eJSEGusCbV9Kgx52X5uorfot5i1bZUJcSKJJby
38UpFzQ4/SOBewNfWAq6Q1NBWUbfn8BARv96L7n3uK4JrxfkUrHGjzWGJmtlgx+b
shJhA/b/35i7KxmdI6eGy0I3vylbGjaH0WGS4+QRYeJKWXPm6kk=
-----END CERTIFICATE-----
Ok, if we want to write directly to a file, nothing could be simpler:
vault kv get -field=certificate secret/infrastructure/certificates/devops-db > test.cert
Want to validate by URL/API:
curl \
--insecure \
--header "X-Vault-Token: hvs.CAESIAZoY7ZYdHNIJgXIEEUJyG2H2p8w6XrvL4MLW_K4kqUPGh4KHGh2cy5ZREk5Y2YycWIxQkpDcTJLdnBLSkwzSlA" \
--request GET \
https://vault.devops-db.internal:8200/v1/secret/data/infrastructure/certificates/devops-db
You can still do an sdiff between the two files to make sure nothing was missed:
sdiff -s ldapserver-cert.crt test.cert
Another way is to load the contents of a file directly, this can even be done by string, but in this case, a cat of the file is enough.
vault kv put secret/infrastructure/certificates/devops-db certificate="$(cat ldapserver-cert.crt)"
================== Secret Path ==================
secret/data/infrastructure/certificates/devops-db
======= Metadata =======
Key Value
--- -----
created_time 2025-03-11T17:35:48.329688131Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 1
For us, at this moment, only the content of the certificate field that we created when we recorded the KV matters.
vault kv get -field=certificate secret/infrastructure/certificates/devops-db
----BEGIN CERTIFICATE-----
MIIFwjCCA6qgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwgYQxCzAJBgNVBAYTAlBU
MQ4wDAYDVQQIDAVQb3J0bzEOMAwGA1UEBwwFUG9ydG8xEjAQBgNVBAoMCURldm9w
cy1EQjEcMBoGA1UEAwwTbGRhcC5kZXZvcHMtZGIuaW5mbzEjMCEGCSqGSIb3DQEJ
ARYUYWRtaW5AZGV2b3BzLWRiLmluZm8wHhcNMjQwNDA4MTEzMzE0WhcNMjUwNDA4
MTEzMzE0WjB0MQswCQYDVQQGEwJQVDEOMAwGA1UECAwFUG9ydG8xEjAQBgNVBAoM
CURldm9wcy1EQjEcMBoGA1UEAwwTbGRhcC5kZXZvcHMtZGIuaW5mbzEjMCEGCSqG
SIb3DQEJARYUYWRtaW5AZGV2b3BzLWRiLmluZm8wggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQCz6rcxPNUdN37jfFmMf/Mwdxmf6ST3hulCJAxNBBHzOSOW
+umvVhfqtw88X3dgq3CW7fQvGQ2izqzN/2MLSe7yV9I1LGqLmtwN2IHTTpC3NAeH
8qlfuwHi+IvO2eFr0EGaL4rT5O+h8qnthPWI1/Rh9xdkx9xvTvVTsElkNZJ+zAZs
E41XwWRsxwHUyDRxQIL2EGbUVyjbJgTzoxQQHdetIeYc6Vya7ABHa6iwfSMKR99A
NdOujpnNecGnGJSzQ0B6RXp2ae28LjjyVdMV1wo6PrvgsKqt5MO4GxyPKginVp0s
ly2zVshCzREw6/4lxxJXqRHcmcS6mhm0U77QTG32A2bU+SJONqxF6GVil60sGm59
MxwDvkgQuE9QDQ4+txYh8K97PfxqVcPG92PS2sYOinc1EBsnD6TEsuvfc8m0Ev3m
njZ+jgJA4Gf+e9AbfgQVJEbdQj7mM2gRFL7CWKAgzk2KRh9xWTlk8nCwqCwHx57d
hE+qfC/SkInZCQHGTSQ22+RidEXq7GxtY2KDNSFSTPeGjR8KA5+lqeuIf8ZeHc6s
HEtK12B8yvYDfRyCBnPugXxs77CiTcmUvWCfBP9GZv4icoCdDTzfnfTNaGO9X16+
XY5sC27o24WsxXLF9EDtp6FpnGX1moR6h89Jky+clCwpDUj4sucWz4WPtHpAnwID
AQABo00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBTP5qF7BCcepDXMDBBq+Bbonlr2
FzAfBgNVHSMEGDAWgBRN6D0ZxNB2qFyd9JTxZ/oYSBfMTjANBgkqhkiG9w0BAQsF
AAOCAgEAjz2Hx2s8A+liNwaEGPS1B/TDHDUKgzsrjXPEVfni3vhlhqgczej/rDAX
d8pLJ4QawlFPbQVZqFFsyJjo6dAG2WfIJeA0c+7kw1pVcbVqQKymq7UtOaHiZF8j
jkBuxKJH4P+lxBLSWCiktvqhTJ/1IgQ66R3wve8J0+KCHGsX2BFMA8Zqc48PTXnu
NGLUsIIYNwMlsCyfEYRY9s6Lg5q8Vcb1dN39uJwMe+Q8XKM0tPM+Dn1z4289q9CZ
poGfhonu3u/9e/LsrptE0ZURGqBFCXXU8gAq0Yg1ViGwcA8e6HC6iia6H0Y4vS6j
q33VIswn0In56zw4gOD/BnYHU5B/277hY8UIsU6vQaTZbpE/GpW8RT85V4MT6r5W
MI2WF8ZATyBbJ5PbXctYfmnydQwTXpoNnioGmxH4Qu0S+ydc+yneAIlZWURlq5gB
YuZrmI7xuGxs5UfzQBEFroRlI6QmW95ebkac5XwURTW1/bI5deJZnfTOezRJKr5n
L1yySSIs2rYXQkphDwV6HqSNg3eJSEGusCbV9Kgx52X5uorfot5i1bZUJcSKJJby
38UpFzQ4/SOBewNfWAq6Q1NBWUbfn8BARv96L7n3uK4JrxfkUrHGjzWGJmtlgx+b
shJhA/b/35i7KxmdI6eGy0I3vylbGjaH0WGS4+QRYeJKWXPm6kk=
-----END CERTIFICATE-----
Ok, if we want to write directly to a file, nothing could be simpler:
vault kv get -field=certificate secret/infrastructure/certificates/devops-db > test.cert
Want to validate by URL/API:
curl \
--insecure \
--header "X-Vault-Token: hvs.CAESIAZoY7ZYdHNIJgXIEEUJyG2H2p8w6XrvL4MLW_K4kqUPGh4KHGh2cy5ZREk5Y2YycWIxQkpDcTJLdnBLSkwzSlA" \
--request GET \
https://vault.devops-db.internal:8200/v1/secret/data/infrastructure/certificates/devops-db
You can still do an sdiff between the two files to make sure nothing was missed:
sdiff -s ldapserver-cert.crt test.cert
Directly from a multiline string.
vault kv put secret/infrastructure/certificates/devops-db certificate=-<<EOF
----BEGIN CERTIFICATE-----
MIIFwjCCA6qgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwgYQxCzAJBgNVBAYTAlBU
MQ4wDAYDVQQIDAVQb3J0bzEOMAwGA1UEBwwFUG9ydG8xEjAQBgNVBAoMCURldm9w
cy1EQjEcMBoGA1UEAwwTbGRhcC5kZXZvcHMtZGIuaW5mbzEjMCEGCSqGSIb3DQEJ
ARYUYWRtaW5AZGV2b3BzLWRiLmluZm8wHhcNMjQwNDA4MTEzMzE0WhcNMjUwNDA4
MTEzMzE0WjB0MQswCQYDVQQGEwJQVDEOMAwGA1UECAwFUG9ydG8xEjAQBgNVBAoM
CURldm9wcy1EQjEcMBoGA1UEAwwTbGRhcC5kZXZvcHMtZGIuaW5mbzEjMCEGCSqG
SIb3DQEJARYUYWRtaW5AZGV2b3BzLWRiLmluZm8wggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQCz6rcxPNUdN37jfFmMf/Mwdxmf6ST3hulCJAxNBBHzOSOW
+umvVhfqtw88X3dgq3CW7fQvGQ2izqzN/2MLSe7yV9I1LGqLmtwN2IHTTpC3NAeH
8qlfuwHi+IvO2eFr0EGaL4rT5O+h8qnthPWI1/Rh9xdkx9xvTvVTsElkNZJ+zAZs
E41XwWRsxwHUyDRxQIL2EGbUVyjbJgTzoxQQHdetIeYc6Vya7ABHa6iwfSMKR99A
NdOujpnNecGnGJSzQ0B6RXp2ae28LjjyVdMV1wo6PrvgsKqt5MO4GxyPKginVp0s
ly2zVshCzREw6/4lxxJXqRHcmcS6mhm0U77QTG32A2bU+SJONqxF6GVil60sGm59
MxwDvkgQuE9QDQ4+txYh8K97PfxqVcPG92PS2sYOinc1EBsnD6TEsuvfc8m0Ev3m
njZ+jgJA4Gf+e9AbfgQVJEbdQj7mM2gRFL7CWKAgzk2KRh9xWTlk8nCwqCwHx57d
hE+qfC/SkInZCQHGTSQ22+RidEXq7GxtY2KDNSFSTPeGjR8KA5+lqeuIf8ZeHc6s
HEtK12B8yvYDfRyCBnPugXxs77CiTcmUvWCfBP9GZv4icoCdDTzfnfTNaGO9X16+
XY5sC27o24WsxXLF9EDtp6FpnGX1moR6h89Jky+clCwpDUj4sucWz4WPtHpAnwID
AQABo00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBTP5qF7BCcepDXMDBBq+Bbonlr2
FzAfBgNVHSMEGDAWgBRN6D0ZxNB2qFyd9JTxZ/oYSBfMTjANBgkqhkiG9w0BAQsF
AAOCAgEAjz2Hx2s8A+liNwaEGPS1B/TDHDUKgzsrjXPEVfni3vhlhqgczej/rDAX
d8pLJ4QawlFPbQVZqFFsyJjo6dAG2WfIJeA0c+7kw1pVcbVqQKymq7UtOaHiZF8j
jkBuxKJH4P+lxBLSWCiktvqhTJ/1IgQ66R3wve8J0+KCHGsX2BFMA8Zqc48PTXnu
NGLUsIIYNwMlsCyfEYRY9s6Lg5q8Vcb1dN39uJwMe+Q8XKM0tPM+Dn1z4289q9CZ
poGfhonu3u/9e/LsrptE0ZURGqBFCXXU8gAq0Yg1ViGwcA8e6HC6iia6H0Y4vS6j
q33VIswn0In56zw4gOD/BnYHU5B/277hY8UIsU6vQaTZbpE/GpW8RT85V4MT6r5W
MI2WF8ZATyBbJ5PbXctYfmnydQwTXpoNnioGmxH4Qu0S+ydc+yneAIlZWURlq5gB
YuZrmI7xuGxs5UfzQBEFroRlI6QmW95ebkac5XwURTW1/bI5deJZnfTOezRJKr5n
L1yySSIs2rYXQkphDwV6HqSNg3eJSEGusCbV9Kgx52X5uorfot5i1bZUJcSKJJby
38UpFzQ4/SOBewNfWAq6Q1NBWUbfn8BARv96L7n3uK4JrxfkUrHGjzWGJmtlgx+b
shJhA/b/35i7KxmdI6eGy0I3vylbGjaH0WGS4+QRYeJKWXPm6kk=
-----END CERTIFICATE-----
EOF
================== Secret Path ==================
secret/data/infrastructure/certificates/devops-db
======= Metadata =======
Key Value
--- -----
created_time 2025-03-12T11:16:43.344273217Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 3
For us, at this moment, only the content of the certificate field that we created when we recorded the KV matters.
vault kv get -field=certificate secret/infrastructure/certificates/devops-db
----BEGIN CERTIFICATE-----
MIIFwjCCA6qgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwgYQxCzAJBgNVBAYTAlBU
MQ4wDAYDVQQIDAVQb3J0bzEOMAwGA1UEBwwFUG9ydG8xEjAQBgNVBAoMCURldm9w
cy1EQjEcMBoGA1UEAwwTbGRhcC5kZXZvcHMtZGIuaW5mbzEjMCEGCSqGSIb3DQEJ
ARYUYWRtaW5AZGV2b3BzLWRiLmluZm8wHhcNMjQwNDA4MTEzMzE0WhcNMjUwNDA4
MTEzMzE0WjB0MQswCQYDVQQGEwJQVDEOMAwGA1UECAwFUG9ydG8xEjAQBgNVBAoM
CURldm9wcy1EQjEcMBoGA1UEAwwTbGRhcC5kZXZvcHMtZGIuaW5mbzEjMCEGCSqG
SIb3DQEJARYUYWRtaW5AZGV2b3BzLWRiLmluZm8wggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQCz6rcxPNUdN37jfFmMf/Mwdxmf6ST3hulCJAxNBBHzOSOW
+umvVhfqtw88X3dgq3CW7fQvGQ2izqzN/2MLSe7yV9I1LGqLmtwN2IHTTpC3NAeH
8qlfuwHi+IvO2eFr0EGaL4rT5O+h8qnthPWI1/Rh9xdkx9xvTvVTsElkNZJ+zAZs
E41XwWRsxwHUyDRxQIL2EGbUVyjbJgTzoxQQHdetIeYc6Vya7ABHa6iwfSMKR99A
NdOujpnNecGnGJSzQ0B6RXp2ae28LjjyVdMV1wo6PrvgsKqt5MO4GxyPKginVp0s
ly2zVshCzREw6/4lxxJXqRHcmcS6mhm0U77QTG32A2bU+SJONqxF6GVil60sGm59
MxwDvkgQuE9QDQ4+txYh8K97PfxqVcPG92PS2sYOinc1EBsnD6TEsuvfc8m0Ev3m
njZ+jgJA4Gf+e9AbfgQVJEbdQj7mM2gRFL7CWKAgzk2KRh9xWTlk8nCwqCwHx57d
hE+qfC/SkInZCQHGTSQ22+RidEXq7GxtY2KDNSFSTPeGjR8KA5+lqeuIf8ZeHc6s
HEtK12B8yvYDfRyCBnPugXxs77CiTcmUvWCfBP9GZv4icoCdDTzfnfTNaGO9X16+
XY5sC27o24WsxXLF9EDtp6FpnGX1moR6h89Jky+clCwpDUj4sucWz4WPtHpAnwID
AQABo00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBTP5qF7BCcepDXMDBBq+Bbonlr2
FzAfBgNVHSMEGDAWgBRN6D0ZxNB2qFyd9JTxZ/oYSBfMTjANBgkqhkiG9w0BAQsF
AAOCAgEAjz2Hx2s8A+liNwaEGPS1B/TDHDUKgzsrjXPEVfni3vhlhqgczej/rDAX
d8pLJ4QawlFPbQVZqFFsyJjo6dAG2WfIJeA0c+7kw1pVcbVqQKymq7UtOaHiZF8j
jkBuxKJH4P+lxBLSWCiktvqhTJ/1IgQ66R3wve8J0+KCHGsX2BFMA8Zqc48PTXnu
NGLUsIIYNwMlsCyfEYRY9s6Lg5q8Vcb1dN39uJwMe+Q8XKM0tPM+Dn1z4289q9CZ
poGfhonu3u/9e/LsrptE0ZURGqBFCXXU8gAq0Yg1ViGwcA8e6HC6iia6H0Y4vS6j
q33VIswn0In56zw4gOD/BnYHU5B/277hY8UIsU6vQaTZbpE/GpW8RT85V4MT6r5W
MI2WF8ZATyBbJ5PbXctYfmnydQwTXpoNnioGmxH4Qu0S+ydc+yneAIlZWURlq5gB
YuZrmI7xuGxs5UfzQBEFroRlI6QmW95ebkac5XwURTW1/bI5deJZnfTOezRJKr5n
L1yySSIs2rYXQkphDwV6HqSNg3eJSEGusCbV9Kgx52X5uorfot5i1bZUJcSKJJby
38UpFzQ4/SOBewNfWAq6Q1NBWUbfn8BARv96L7n3uK4JrxfkUrHGjzWGJmtlgx+b
shJhA/b/35i7KxmdI6eGy0I3vylbGjaH0WGS4+QRYeJKWXPm6kk=
-----END CERTIFICATE-----
Ok, if we want to write directly to a file, nothing could be simpler:
vault kv get -field=certificate secret/infrastructure/certificates/devops-db > test.cert
Want to validate by URL/API:
curl \
--insecure \
--header "X-Vault-Token: hvs.CAESIAZoY7ZYdHNIJgXIEEUJyG2H2p8w6XrvL4MLW_K4kqUPGh4KHGh2cy5ZREk5Y2YycWIxQkpDcTJLdnBLSkwzSlA" \
--request GET \
https://vault.devops-db.internal:8200/v1/secret/data/infrastructure/certificates/devops-db
You can still do an sdiff between the two files to make sure nothing was missed:
sdiff -s ldapserver-cert.crt test.cert
As I said before, some files may need to be converted to Base64, due to the type of their content.
vault kv put secret/infrastructure/certificates/devops-db-b64 certificate="$(base64 /work/vault/cert/ldapserver-cert.crt)"
==================== Secret Path ====================
secret/data/infrastructure/certificates/devops-db-b64
======= Metadata =======
Key Value
--- -----
created_time 2025-03-12T11:22:40.307821312Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 3
The recovery is the same as the other methods, however, you will have to decode from Base64.
vault kv get -field=certificate -mount="secret" "infrastructure/certificates/devops-db-b64" | base64 --decode
----BEGIN CERTIFICATE-----
MIIFwjCCA6qgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwgYQxCzAJBgNVBAYTAlBU
MQ4wDAYDVQQIDAVQb3J0bzEOMAwGA1UEBwwFUG9ydG8xEjAQBgNVBAoMCURldm9w
cy1EQjEcMBoGA1UEAwwTbGRhcC5kZXZvcHMtZGIuaW5mbzEjMCEGCSqGSIb3DQEJ
ARYUYWRtaW5AZGV2b3BzLWRiLmluZm8wHhcNMjQwNDA4MTEzMzE0WhcNMjUwNDA4
MTEzMzE0WjB0MQswCQYDVQQGEwJQVDEOMAwGA1UECAwFUG9ydG8xEjAQBgNVBAoM
CURldm9wcy1EQjEcMBoGA1UEAwwTbGRhcC5kZXZvcHMtZGIuaW5mbzEjMCEGCSqG
SIb3DQEJARYUYWRtaW5AZGV2b3BzLWRiLmluZm8wggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQCz6rcxPNUdN37jfFmMf/Mwdxmf6ST3hulCJAxNBBHzOSOW
+umvVhfqtw88X3dgq3CW7fQvGQ2izqzN/2MLSe7yV9I1LGqLmtwN2IHTTpC3NAeH
8qlfuwHi+IvO2eFr0EGaL4rT5O+h8qnthPWI1/Rh9xdkx9xvTvVTsElkNZJ+zAZs
E41XwWRsxwHUyDRxQIL2EGbUVyjbJgTzoxQQHdetIeYc6Vya7ABHa6iwfSMKR99A
NdOujpnNecGnGJSzQ0B6RXp2ae28LjjyVdMV1wo6PrvgsKqt5MO4GxyPKginVp0s
ly2zVshCzREw6/4lxxJXqRHcmcS6mhm0U77QTG32A2bU+SJONqxF6GVil60sGm59
MxwDvkgQuE9QDQ4+txYh8K97PfxqVcPG92PS2sYOinc1EBsnD6TEsuvfc8m0Ev3m
njZ+jgJA4Gf+e9AbfgQVJEbdQj7mM2gRFL7CWKAgzk2KRh9xWTlk8nCwqCwHx57d
hE+qfC/SkInZCQHGTSQ22+RidEXq7GxtY2KDNSFSTPeGjR8KA5+lqeuIf8ZeHc6s
HEtK12B8yvYDfRyCBnPugXxs77CiTcmUvWCfBP9GZv4icoCdDTzfnfTNaGO9X16+
XY5sC27o24WsxXLF9EDtp6FpnGX1moR6h89Jky+clCwpDUj4sucWz4WPtHpAnwID
AQABo00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBTP5qF7BCcepDXMDBBq+Bbonlr2
FzAfBgNVHSMEGDAWgBRN6D0ZxNB2qFyd9JTxZ/oYSBfMTjANBgkqhkiG9w0BAQsF
AAOCAgEAjz2Hx2s8A+liNwaEGPS1B/TDHDUKgzsrjXPEVfni3vhlhqgczej/rDAX
d8pLJ4QawlFPbQVZqFFsyJjo6dAG2WfIJeA0c+7kw1pVcbVqQKymq7UtOaHiZF8j
jkBuxKJH4P+lxBLSWCiktvqhTJ/1IgQ66R3wve8J0+KCHGsX2BFMA8Zqc48PTXnu
NGLUsIIYNwMlsCyfEYRY9s6Lg5q8Vcb1dN39uJwMe+Q8XKM0tPM+Dn1z4289q9CZ
poGfhonu3u/9e/LsrptE0ZURGqBFCXXU8gAq0Yg1ViGwcA8e6HC6iia6H0Y4vS6j
q33VIswn0In56zw4gOD/BnYHU5B/277hY8UIsU6vQaTZbpE/GpW8RT85V4MT6r5W
MI2WF8ZATyBbJ5PbXctYfmnydQwTXpoNnioGmxH4Qu0S+ydc+yneAIlZWURlq5gB
YuZrmI7xuGxs5UfzQBEFroRlI6QmW95ebkac5XwURTW1/bI5deJZnfTOezRJKr5n
L1yySSIs2rYXQkphDwV6HqSNg3eJSEGusCbV9Kgx52X5uorfot5i1bZUJcSKJJby
38UpFzQ4/SOBewNfWAq6Q1NBWUbfn8BARv96L7n3uK4JrxfkUrHGjzWGJmtlgx+b
shJhA/b/35i7KxmdI6eGy0I3vylbGjaH0WGS4+QRYeJKWXPm6kk=
-----END CERTIFICATE-----
To write directly to a file:
vault kv get -field=certificate -mount="secret" "infrastructure/certificates/devops-db-b64" | base64 --decode> test.cert
Also example using the API/URL in conjunction with JQ and Base64 Decode:
curl \
--insecure \
--header "X-Vault-Token: hvs.CAESIAZoY7ZYdHNIJgXIEEUJyG2H2p8w6XrvL4MLW_K4kqUPGh4KHGh2cy5ZREk5Y2YycWIxQkpDcTJLdnBLSkwzSlA" \
--request GET \
https://vault.devops-db.internal:8200/v1/secret/data/infrastructure/certificates/devops-db-b64 | jq '.data.data.certificate' -r | base64 --decode