From 2395621b41cb2410f95f92ef2b49eb67fc2077ce Mon Sep 17 00:00:00 2001 From: Grayson Miller <104777457+vertigo-one@users.noreply.github.com> Date: Tue, 6 Aug 2024 15:58:15 -0500 Subject: [PATCH 1/5] new branch for examples Signed-off-by: Grayson Miller <104777457+vertigo-one@users.noreply.github.com> --- examples/ansible/README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 examples/ansible/README.md diff --git a/examples/ansible/README.md b/examples/ansible/README.md new file mode 100644 index 00000000..e3b755f9 --- /dev/null +++ b/examples/ansible/README.md @@ -0,0 +1,2 @@ +# Ansible Playbooks to run Vcert + From c9f4bca875e1c7afd1a4fb1c12726a8f8f41a619 Mon Sep 17 00:00:00 2001 From: Grayson Miller <104777457+vertigo-one@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:19:05 -0500 Subject: [PATCH 2/5] Add Readme for ansible examples Signed-off-by: Grayson Miller <104777457+vertigo-one@users.noreply.github.com> --- examples/ansible/README.md | 64 +++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/examples/ansible/README.md b/examples/ansible/README.md index e3b755f9..d43fa454 100644 --- a/examples/ansible/README.md +++ b/examples/ansible/README.md @@ -1,2 +1,64 @@ -# Ansible Playbooks to run Vcert +# Ansible Playbooks to Run VCert Playbooks Against the Venafi Control Plane + +This folder contains sample Ansible playbooks that can be used to trigger [VCert Playbooks](https://github.com/Venafi/vcert/blob/master/README-PLAYBOOK.md) using Venafi Control Plane (VCP) [Service Accounts](https://docs.venafi.cloud/vcs-platform/serviceaccounts/about-service-accounts/). + +These ansible playbooks allow VCert playbooks to be executed without storing the credentials localy on the managed VMs. This is done by authentiating only once to your IDP on the ansible control node, and then executing a Vcert Playbook on each managed VM using the resulting temporary JSON Web Token (JWT) as the authentication credential to VCP. Ansible then injects the JWT into an environment variable that VCert will read when ansible executes the vcert playbook on the VM. Once VCert finishes running the shell session is closed, and the JWT is no longer avaliable on the VM. Additionally, this menthod allows the VM owners to control the VCert playbook if they so chose, however, it is possible for ansible to manage the VCert Playbook file if required. + +**IDP support note:** If your IDP does not have an example ansible playbook that does not mean that it is impossible to use it. It only means that an example does not exist in this repository for it. The likely reason is lack of access or time to devote to learning the IDP. Contributions of ansible playbooks for other IDPs are welcome. + +## Rquirements + +Each Sample uses: +- A VCP [Custom API integration](https://docs.venafi.cloud/vcs-platform/serviceaccounts/c-about-custom-api-integration-sa/) Service Account +- A OAuth2.0 enabled application or OAuth API integration with an IDP that will return a [JSON Web Token (JWT)](https://jwt.io/) +- The OAuth 2.0 Client Credential authentication method for authenticating to the IDP Oauth2.0 endpoint. + +Prior Work you must do before usingg these playbooks: +- VCert must be installed on all servers that you wish to run playbooks on. + -** Note:** the playbooks assume VCert is installed in your PATH. If it is not, you will need to edit the playbooks to contain the full path to the VCert binary. +- A VCP Custom API Intgration Service account already configured in TLSPC. +- An application or API integration must be configured in your IDP + +Required Information - All playbooks +- The **Client ID** of your application in your IDP +- The **Client Secret** associated with your Client ID +- The **Oauth2.0 Token URL** of your IDP +- The **Path to the VCert Playbook file** that you wish to execute on your servers/inventory. This must be the complete, fully qualified, path and must be the same on all servers you wish to run it on. + - The [VCert Playbook](https://github.com/Venafi/vcert/blob/master/README-PLAYBOOK.md) should contain your SVC Account Token Url as the value for `tokenURL` inside of the `credentials` block in the playbook. +- An **ansible inventory** containing the servers you wish to run Vcert Playbooks on using this VCP service account. + + +## Playbook flow +```mermaid +--- +title: Playbook Execution +--- +%%{init: {"flowchart": {"htmlLabels": false}} }%% + + +flowchart LR + subgraph Ansible_Control_Node + authenticate(Authenticate to IDP using OAuth 2.0 Client Credentials) --> JWT + end + + subgraph Managed_Server + injectcredentials(Add JWT to environment as TLSPC_EXTERNAL_JWT) + runvcert(vcert run --file $Vcert_Playbook_Path) + + injectcredentials --> runvcert + runvcert --> vcert + subgraph vcert + direction TB + vcpauth(Authenticate to VCP using JWT to get VCP access token) + reqestcert("Request certificate(s) from TLSPC using access token") + installcert("Install certificates(s) on machine") + postinstall(Run Post-installation actions if configured) + + vcpauth --> reqestcert --> installcert --> postinstall + end + end + + Start --> Ansible_Control_Node + Ansible_Control_Node --> Managed_Server +``` From 3ea84419efb36bdd81ef48fcf1a97809d1667191 Mon Sep 17 00:00:00 2001 From: Grayson Miller <104777457+vertigo-one@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:19:30 -0500 Subject: [PATCH 3/5] Add ansible playbook and vcert playbook example Signed-off-by: Grayson Miller <104777457+vertigo-one@users.noreply.github.com> --- .../oauth2.ADFS_clientcredentials.yaml | 46 +++++++++++++++++++ .../oauth2.Auth0_clientcredentials.yaml | 42 +++++++++++++++++ .../oauth2.AzureEntra_clientcredentials.yaml | 41 +++++++++++++++++ examples/ansible/testvcertplaybook.yaml | 20 ++++++++ 4 files changed, 149 insertions(+) create mode 100644 examples/ansible/oauth2.ADFS_clientcredentials.yaml create mode 100644 examples/ansible/oauth2.Auth0_clientcredentials.yaml create mode 100644 examples/ansible/oauth2.AzureEntra_clientcredentials.yaml create mode 100644 examples/ansible/testvcertplaybook.yaml diff --git a/examples/ansible/oauth2.ADFS_clientcredentials.yaml b/examples/ansible/oauth2.ADFS_clientcredentials.yaml new file mode 100644 index 00000000..587872fe --- /dev/null +++ b/examples/ansible/oauth2.ADFS_clientcredentials.yaml @@ -0,0 +1,46 @@ +--- +- name: Authenticate to ADFS OAuth2.0 provider using Client Credentials Flow. + hosts: localhost + vars: + # The value of these variables are specific to the Application that is being automated. + # Each application or team should have a separate IDP application integration with separate credentials. + # Reuse of the same IDP integration across the entire company is not advised due to the access + # the Venafi service account will need to be given inside the TLSPC platform. + idp_token_url: + idp_audience: + idp_client_id: + idp_client_secret: + + tasks: + - name: Authenticate to ADFS + ansible.builtin.uri: + url: '{{ idp_token_url }}' + method: POST + body_format: form-urlencoded + body: + # ADFS's Scope parameter is in format of / and provides both to the platform. + - [ scope, '{{ idp_audience }}/openid'] + # A redirect URI is needed as ADFS uses it along with the Client_id to to determine which + # Application Group and Server Application you are authenticating as. + # It must match exactly what is in your application group. + - [ redirect_uri, "http://localhost"] + - [ client_id, '{{ idp_client_id }}' ] + - [ client_secret, '{{ idp_client_secret }}' ] + - [ grant_type, client_credentials ] + status_code: 200 + register: auth + +- name: Execute VCert Playbook on WebApp Servers + #hosts: my_app_servers + hosts: + vars: + # The fully qualified path to the Vcert Playbook file is stored here. + # This should be the same for all hosts in the chosen inventory. + vcert_playbook_path: + + tasks: + - name : Execute VCert playbook with JWT. + shell: vcert run --file '{{ vcert_playbook_path }}' + environment: + TLSPC_EXTERNAL_JWT: '{{ auth.json.access_token }}' + diff --git a/examples/ansible/oauth2.Auth0_clientcredentials.yaml b/examples/ansible/oauth2.Auth0_clientcredentials.yaml new file mode 100644 index 00000000..dceab362 --- /dev/null +++ b/examples/ansible/oauth2.Auth0_clientcredentials.yaml @@ -0,0 +1,42 @@ +--- +- name: Authenticate to Auth0 OAuth2.0 provider using Client Credentials Flow. + hosts: localhost + vars: + # The value of these variables are specific to the Application that is being automated. + # Each application or team should have a separate IDP application integration with separate credentials. + # Reuse of the same IDP integration across the entire company is not advised due to the access + # the Venafi service account will need to be given inside the TLSPC platform. + idp_token_url: + idp_audience: + idp_client_id: + idp_client_secret: + + tasks: + - name: Authenticate to Auth0 + ansible.builtin.uri: + url: '{{ idp_token_url }}' + method: POST + body_format: form-urlencoded + body: + - [ audience, '{{ idp_audience }}'] + - [ scope, certificates:request ] + - [ client_id, '{{ idp_client_id }}' ] + - [ client_secret, '{{ idp_client_secret }}' ] + - [ grant_type, client_credentials ] + status_code: 200 + register: auth + +- name: Execute VCert Playbook on WebApp Servers + #hosts: my_app_servers + hosts: + vars: + # The fully qualified path to the Vcert Playbook file is stored here. + # This should be the same for all hosts in the chosen inventory. + vcert_playbook_path: + + tasks: + - name : Execute VCert playbook with JWT. + shell: vcert run --file '{{ vcert_playbook_path }}' + environment: + TLSPC_EXTERNAL_JWT: '{{ auth.json.access_token }}' + diff --git a/examples/ansible/oauth2.AzureEntra_clientcredentials.yaml b/examples/ansible/oauth2.AzureEntra_clientcredentials.yaml new file mode 100644 index 00000000..b79d8e9c --- /dev/null +++ b/examples/ansible/oauth2.AzureEntra_clientcredentials.yaml @@ -0,0 +1,41 @@ +--- +- name: Authenticate to Azure Entra ID's OAuth2.0 provider using Client Credentials Flow. + hosts: localhost + vars: + # The value of these variables are specific to the Application that is being automated. + # Each application or team should have a separate IDP application integration with separate credentials. + # Reuse of the same IDP integration across the entire company is not advised due to the access + # the Venafi service account will need to be given inside the TLSPC platform. + idp_token_url: + idp_client_id: + idp_client_secret: + + tasks: + - name: Authenticate to Azure Entra ID + ansible.builtin.uri: + url: '{{ idp_token_url }}' + method: POST + body_format: form-urlencoded + body: + # Azure Entra ID's scope parameter can be .default to get the default scope and can be much more complicated if you want it to be. + - [ scope, 'certificates:request'] + - [ client_id, '{{ idp_client_id }}' ] + - [ client_secret, '{{ idp_client_secret }}' ] + - [ grant_type, client_credentials ] + status_code: 200 + register: auth + +- name: Execute VCert Playbook on WebApp Servers + #hosts: my_app_servers + hosts: + vars: + # The fully qualified path to the Vcert Playbook file is stored here. + # This should be the same for all hosts in the chosen inventory. + vcert_playbook_path: + + tasks: + - name : Execute VCert playbook with JWT. + shell: vcert run --file '{{ vcert_playbook_path }}' + environment: + TLSPC_EXTERNAL_JWT: '{{ auth.json.access_token }}' + diff --git a/examples/ansible/testvcertplaybook.yaml b/examples/ansible/testvcertplaybook.yaml new file mode 100644 index 00000000..aafae5d8 --- /dev/null +++ b/examples/ansible/testvcertplaybook.yaml @@ -0,0 +1,20 @@ +config: + connection: + platform: vaas + credentials: + tokenURL: + externalJWT: '{{ Env "TLSPC_EXTERNAL_JWT" }}' +certificateTasks: + - name: myCertificate + renewBefore: 31d + request: + csr: service + subject: + commonName: "ansibletest.lab.corp.net" + zone: "\\" + installations: + - format: PEM + file: "./cert.cer" + chainFile: "./chain.cer" + keyFile: "./key.pem" + afterInstallAction: "echo Success!!!" \ No newline at end of file From 2c40e6de8e45a84d033662d4a79557cff74d7f3d Mon Sep 17 00:00:00 2001 From: Grayson Miller <104777457+vertigo-one@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:23:44 -0500 Subject: [PATCH 4/5] spelling and formatting. Signed-off-by: Grayson Miller <104777457+vertigo-one@users.noreply.github.com> --- examples/ansible/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/ansible/README.md b/examples/ansible/README.md index d43fa454..e34bef33 100644 --- a/examples/ansible/README.md +++ b/examples/ansible/README.md @@ -13,9 +13,9 @@ Each Sample uses: - A OAuth2.0 enabled application or OAuth API integration with an IDP that will return a [JSON Web Token (JWT)](https://jwt.io/) - The OAuth 2.0 Client Credential authentication method for authenticating to the IDP Oauth2.0 endpoint. -Prior Work you must do before usingg these playbooks: +Prior Work you must do before using these playbooks: - VCert must be installed on all servers that you wish to run playbooks on. - -** Note:** the playbooks assume VCert is installed in your PATH. If it is not, you will need to edit the playbooks to contain the full path to the VCert binary. + - **Note:** the playbooks assume VCert is installed in your PATH. If it is not, you will need to edit the playbooks to contain the full path to the VCert binary. - A VCP Custom API Intgration Service account already configured in TLSPC. - An application or API integration must be configured in your IDP From bf95fa38a9b528b083446a14790d1543abd39f06 Mon Sep 17 00:00:00 2001 From: Grayson Miller <104777457+vertigo-one@users.noreply.github.com> Date: Tue, 27 Aug 2024 13:18:14 -0500 Subject: [PATCH 5/5] update playbook: local csr, env var options, more comments, SANS Signed-off-by: Grayson Miller <104777457+vertigo-one@users.noreply.github.com> --- examples/ansible/testvcertplaybook.yaml | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/examples/ansible/testvcertplaybook.yaml b/examples/ansible/testvcertplaybook.yaml index aafae5d8..d2c40b2f 100644 --- a/examples/ansible/testvcertplaybook.yaml +++ b/examples/ansible/testvcertplaybook.yaml @@ -5,16 +5,24 @@ config: tokenURL: externalJWT: '{{ Env "TLSPC_EXTERNAL_JWT" }}' certificateTasks: - - name: myCertificate + - name: appcert + setEnvVars: #delete the environment variables that you do not need. + - "thumbprint" #VCERT_TASKNAME_THUMBPRINT + - "serial" #VCERT_TASKNAME_SERIAL + - "base64" #VCERT_TASKNAME_BASE64 renewBefore: 31d - request: - csr: service + request: #change the request parameters to fit your certificate needs. + csr: local subject: - commonName: "ansibletest.lab.corp.net" + commonName: 'myapp.corp.net' + sanDNS: + - 'myapp.corp.net' zone: "\\" installations: - format: PEM file: "./cert.cer" chainFile: "./chain.cer" keyFile: "./key.pem" - afterInstallAction: "echo Success!!!" \ No newline at end of file + backupFiles: false + #replace "TASKNAME" below with the name of the certificxate task that the after install action will run for. Example: VCERT_APPCERT_SERIAL + afterInstallAction: "echo $VCERT_TASKNAME_THUMBPRINT $VCERT_TASKNAME_SERIAL $VCERT_TASKNAME_BASE64" \ No newline at end of file