-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bring intermediate CA setup into the app (#35)
* Application now configures vault engines for certs and KV at startup
- Loading branch information
Showing
11 changed files
with
234 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,15 +11,13 @@ services: | |
- 3000:3000 | ||
# Overrides default command so things don't shut down after the process ends. | ||
command: sleep infinity | ||
# Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function. | ||
networks: | ||
astral: | ||
ipv4_address: "10.1.10.200" | ||
environment: | ||
VAULT_ADDR: http://10.1.10.100:8200 | ||
VAULT_ADDR: http://vault:8200 | ||
VAULT_TOKEN: root_token | ||
VAULT_ROOT_CA_MOUNT: pki | ||
VAULT_ROOT_CA_REF: root-ca | ||
JWT_SIGNING_KEY: jwt_secret | ||
APP_REGISTRY_ADDR: http://10.1.10.150:8800 | ||
APP_REGISTRY_ADDR: http://app_registry:8800 | ||
APP_REGISTRY_TOKEN: app_reg_token | ||
|
||
vault: | ||
|
@@ -30,9 +28,6 @@ services: | |
environment: | ||
VAULT_DEV_ROOT_TOKEN_ID: root_token | ||
VAULT_DEV_LISTEN_ADDRESS: 0.0.0.0:8200 | ||
networks: | ||
astral: | ||
ipv4_address: "10.1.10.100" | ||
|
||
app_registry: | ||
image: node:latest | ||
|
@@ -41,16 +36,6 @@ services: | |
- 8800:8800 | ||
volumes: | ||
- .:/data | ||
networks: | ||
astral: | ||
ipv4_address: "10.1.10.150" | ||
command: > | ||
sh -c "npm install -g [email protected] && | ||
json-server /data/app_reg_db.json --routes /data/app_reg_routes.json --port 8800 --host 0.0.0.0" | ||
networks: | ||
astral: | ||
ipam: | ||
driver: default | ||
config: | ||
- subnet: "10.1.10.0/24" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,29 @@ | ||
module Clients | ||
class Vault | ||
class << self | ||
def issue_cert(cert_issue_request) | ||
opts = cert_issue_request.attributes | ||
# Generate the TLS certificate using the intermediate CA | ||
tls_cert = client.logical.write(Rails.configuration.astral[:vault_cert_path], opts) | ||
OpenStruct.new tls_cert.data | ||
end | ||
|
||
def kv_read(path) | ||
client.kv(kv_mount).read(path) | ||
end | ||
|
||
def kv_write(path, data) | ||
enable_engine(kv_mount, "kv-v2") | ||
client.logical.write("#{kv_mount}/data/#{path}", data: data) | ||
end | ||
|
||
def kv_delete(path) | ||
client.logical.delete("#{kv_mount}/data/#{path}") | ||
end | ||
|
||
private | ||
|
||
def client | ||
::Vault::Client.new( | ||
address: Rails.configuration.astral[:vault_addr], | ||
token: Rails.configuration.astral[:vault_token] | ||
address: vault_address, | ||
token: vault_token | ||
) | ||
end | ||
|
||
def enable_engine(mount, type) | ||
# create the engine mount if not present already | ||
unless client.sys.mounts.key?(mount.to_sym) | ||
client.sys.mount(mount, type, "#{type} secrets engine") | ||
end | ||
rescue ::Vault::HTTPError => e | ||
Rails.logger.error "Error enabling #{type} engine: #{e}" | ||
def vault_address | ||
Rails.configuration.astral[:vault_addr] | ||
end | ||
|
||
def vault_token | ||
Rails.configuration.astral[:vault_token] | ||
end | ||
|
||
def kv_mount | ||
Rails.configuration.astral[:vault_kv_mount] | ||
def enable_engine(mount, type) | ||
client.sys.mount(mount, type, "#{type} secrets engine") | ||
end | ||
end | ||
end | ||
|
||
require_relative "vault/key_value" | ||
require_relative "vault/certificate" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
module Clients | ||
class Vault | ||
class << self | ||
def issue_cert(cert_issue_request) | ||
opts = cert_issue_request.attributes | ||
# Generate the TLS certificate using the intermediate CA | ||
tls_cert = client.logical.write(cert_path, opts) | ||
OpenStruct.new tls_cert.data | ||
end | ||
|
||
def configure_pki | ||
if enable_ca | ||
sign_cert | ||
configure_ca | ||
end | ||
end | ||
|
||
private | ||
|
||
def intermediate_ca_mount | ||
"pki_astral" | ||
end | ||
|
||
def cert_path | ||
"#{intermediate_ca_mount}/issue/astral" | ||
end | ||
|
||
def root_ca_ref | ||
Rails.configuration.astral[:vault_root_ca_ref] | ||
end | ||
|
||
def root_ca_mount | ||
Rails.configuration.astral[:vault_root_ca_mount] | ||
end | ||
|
||
def cert_engine_type | ||
"pki" | ||
end | ||
|
||
def enable_ca | ||
# if mount exists, assume configuration is done | ||
if client.sys.mounts.key?(intermediate_ca_mount.to_sym) | ||
return false | ||
end | ||
|
||
# create the mount | ||
enable_engine(intermediate_ca_mount, cert_engine_type) | ||
true | ||
end | ||
|
||
def sign_cert | ||
# Generate intermediate CSR | ||
intermediate_csr = client.logical.write("#{intermediate_ca_mount}/intermediate/generate/internal", | ||
common_name: "astral.internal Intermediate Authority", | ||
issuer_name: "astral-intermediate").data[:csr] | ||
|
||
# Save the intermediate CSR | ||
File.write("tmp/pki_intermediate.csr", intermediate_csr) | ||
|
||
# Sign the intermediate certificate with the root CA | ||
intermediate_cert = client.logical.write("#{root_ca_mount}/root/sign-intermediate", | ||
issuer_ref: root_ca_ref, | ||
csr: intermediate_csr, | ||
format: "pem_bundle", | ||
ttl: "43800h").data[:certificate] | ||
|
||
# Save the signed intermediate certificate | ||
File.write("tmp/intermediate.cert.pem", intermediate_cert) | ||
|
||
# Set the signed intermediate certificate | ||
client.logical.write("#{intermediate_ca_mount}/intermediate/set-signed", certificate: intermediate_cert) | ||
end | ||
|
||
def configure_ca | ||
# Configure the intermediate CA | ||
client.logical.write("#{intermediate_ca_mount}/config/cluster", | ||
path: "#{vault_address}/v1/#{intermediate_ca_mount}", | ||
aia_path: "#{vault_address}/v1/#{intermediate_ca_mount}") | ||
|
||
# Configure the role for issuing certs | ||
issuer_ref = client.logical.read("#{intermediate_ca_mount}/config/issuers").data[:default] | ||
client.logical.write("#{intermediate_ca_mount}/roles/astral", | ||
issuer_ref: issuer_ref, | ||
allow_any_name: true, | ||
max_ttl: "720h", | ||
no_store: false) | ||
|
||
client.logical.write("#{intermediate_ca_mount}/config/urls", | ||
issuing_certificates: "{{cluster_aia_path}}/issuer/{{issuer_id}}/der", | ||
crl_distribution_points: "{{cluster_aia_path}}/issuer/{{issuer_id}}/crl/der", | ||
ocsp_servers: "{{cluster_path}}/ocsp", | ||
enable_templating: true) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
module Clients | ||
class Vault | ||
class << self | ||
def kv_read(path) | ||
client.kv(kv_mount).read(path) | ||
end | ||
|
||
def kv_write(path, data) | ||
configure_kv | ||
client.logical.write("#{kv_mount}/data/#{path}", data: data) | ||
end | ||
|
||
def kv_delete(path) | ||
client.logical.delete("#{kv_mount}/data/#{path}") | ||
end | ||
|
||
def configure_kv | ||
unless client.sys.mounts.key?(kv_mount.to_sym) | ||
enable_engine(kv_mount, kv_engine_type) | ||
end | ||
end | ||
|
||
private | ||
|
||
def kv_mount | ||
"kv_astral" | ||
end | ||
|
||
def kv_engine_type | ||
"kv-v2" | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.