From fcda8bb0b8bcbbe6e7e3a749bcb581959dc89f5c Mon Sep 17 00:00:00 2001 From: Russel Vela Date: Mon, 1 Apr 2024 16:54:54 -0600 Subject: [PATCH 1/6] feat(svc-account): Adds ability to obtain ConnectorType from Platform enum Closes VC-31982 --- pkg/venafi/platform.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/venafi/platform.go b/pkg/venafi/platform.go index 583c936c..71ba37d4 100644 --- a/pkg/venafi/platform.go +++ b/pkg/venafi/platform.go @@ -19,6 +19,7 @@ package venafi import ( "strings" + "github.com/Venafi/vcert/v5/pkg/endpoint" "gopkg.in/yaml.v3" ) @@ -89,6 +90,11 @@ func (p *Platform) UnmarshalYAML(value *yaml.Node) error { return nil } +// GetConnectorType converts the Platform value to an endpoint.ConnectorType value. With aims to make easier to use one or another +func (p Platform) GetConnectorType() endpoint.ConnectorType { + return endpoint.ConnectorType(p) +} + func GetPlatformType(platformString string) Platform { switch strings.ToUpper(platformString) { case strPlatformFake: From 7f48a1f93819c6d30a00bb9793ffc4a5df53e75e Mon Sep 17 00:00:00 2001 From: Russel Vela Date: Mon, 1 Apr 2024 17:44:03 -0600 Subject: [PATCH 2/6] feat(svc-account): Returns proper unauthorized error Returns proper 401 Unauthorized error when TLSPC access token is not valid Closes VC-31982 --- pkg/venafi/cloud/cloud.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/venafi/cloud/cloud.go b/pkg/venafi/cloud/cloud.go index 9f80e62e..81573ed1 100644 --- a/pkg/venafi/cloud/cloud.go +++ b/pkg/venafi/cloud/cloud.go @@ -630,6 +630,8 @@ func parseApplicationDetailsResult(httpStatusCode int, httpStatus string, body [ return parseApplicationDetailsData(body) case http.StatusBadRequest: return nil, verror.ApplicationNotFoundError + case http.StatusUnauthorized: + return nil, fmt.Errorf("%w: %s", verror.ServerError, httpStatus) default: respErrors, err := parseResponseErrors(body) if err != nil { From 01eb5768c2618622e57a766248dd98c4d2005152 Mon Sep 17 00:00:00 2001 From: Russel Vela Date: Mon, 1 Apr 2024 17:46:38 -0600 Subject: [PATCH 3/6] feat(svc-account): Returns proper unauthorized error Returns proper 401 Unauthorized error when TLSPC access token is not valid Closes VC-31982 --- pkg/venafi/cloud/connector.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/venafi/cloud/connector.go b/pkg/venafi/cloud/connector.go index f773ef8e..879f1628 100644 --- a/pkg/venafi/cloud/connector.go +++ b/pkg/venafi/cloud/connector.go @@ -200,6 +200,9 @@ func (c *Connector) ReadZoneConfiguration() (config *endpoint.ZoneConfiguration, if err != nil { return } + } else { + // an error happened, return now + return } } if template == nil { From a2f8e302b6fa80aef96092dc44065ad2f452af34 Mon Sep 17 00:00:00 2001 From: Russel Vela Date: Mon, 1 Apr 2024 17:49:53 -0600 Subject: [PATCH 4/6] feat(svc-account): Returns proper unauthorized error Returns proper 401 Unauthorized error when TLSPC access token is not valid Closes VC-31982 --- pkg/venafi/platform.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/venafi/platform.go b/pkg/venafi/platform.go index 71ba37d4..7830270e 100644 --- a/pkg/venafi/platform.go +++ b/pkg/venafi/platform.go @@ -19,8 +19,9 @@ package venafi import ( "strings" - "github.com/Venafi/vcert/v5/pkg/endpoint" "gopkg.in/yaml.v3" + + "github.com/Venafi/vcert/v5/pkg/endpoint" ) type Platform int From 628489959732e4c22c482d928cc333c9fb8b3406 Mon Sep 17 00:00:00 2001 From: Russel Vela Date: Tue, 2 Apr 2024 07:54:49 -0600 Subject: [PATCH 5/6] feat(svc-account): Adds CHANGELOG.md Closes VC-31982 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..379347d6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,8 @@ +## 5.6.1 (April 2nd, 2024) +- Adds UserAgent header to api requests for TPP, Cloud and Firefly connectors +- Adds functionality to convert a Platform type to a ConnectorType enum + +## 5.6.0 (March 28th, 2024) + - Adds support for service account authentication in TLSPC connector + - Adds new attributes to CLI `getcred` command: `tenant-id` and `external-jwt` for service account authentication + - Adds support for service account authentication to VCert playbooks \ No newline at end of file From cb2119452b13b614a7c455f0778c40cd461b35cd Mon Sep 17 00:00:00 2001 From: Russel Vela Date: Tue, 2 Apr 2024 11:26:05 -0600 Subject: [PATCH 6/6] feat(svc-account): Updates documentation to add service account authentication details Closes VC-31621 --- README-CLI-CLOUD.md | 88 +++++++++++++++++++++++++++++++++++---------- README-PLAYBOOK.md | 14 ++++---- README.md | 10 +++--- 3 files changed, 82 insertions(+), 30 deletions(-) diff --git a/README-CLI-CLOUD.md b/README-CLI-CLOUD.md index 1e8ab4d1..bec076d8 100644 --- a/README-CLI-CLOUD.md +++ b/README-CLI-CLOUD.md @@ -48,8 +48,10 @@ Review these prerequistes to get started. You'll need the following: [https://api.venafi.eu](https://api.venafi.eu/vaas) (if you have an EU account) is accessible from the system where VCert will be run. 2. You have successfully registered for a Venafi as a Service account, have been granted at least the "Resource Owner" role, and know your API key. You can use the `getcred` action to -[register and obtain an API key](#registering-and-obtaining-an-api-key) but you will need an administrator -to update your role if there are already 3 or more users registered for your company in Venafi as a Service. +[register and obtain an API key](#registering-and-obtaining-an-api-key), but you will need an administrator +to update your role if there are already 3 or more users registered for your company in Venafi as a Service. +Alternatively, you have configured a service account, the service account has been granted the "Resource Owner" role, +you know the `tenant ID` and have obtained a `JWT` from the Identity Provider associated to the service-account. 3. A CA Account and Issuing Template exist and have been configured with: 1. Recommended Settings values for: 1. Organizational Unit (OU) @@ -71,26 +73,43 @@ and you know the Application Name. The following options apply to the `enroll`, `pickup`, and `renew` actions: -|         Command         | Description | -|---------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `--config` | Use to specify INI configuration file containing connection details. Available parameters: `cloud_apikey`, `cloud_zone`, `trust_bundle`, `test_mode` | -| `--k` | Use to specify your API key for Venafi as a Service.
Example: -k aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee | -| `--no-prompt` | Use to exclude password prompts. If you enable the prompt and you enter incorrect information, an error is displayed. This option is useful with scripting. | -| `--test-mode` | Use to test operations without connecting to Venafi as a Service. This option is useful for integration tests where the test environment does not have access to Venafi as a Service. Default is false. | -| `--test-mode-delay` | Use to specify the maximum number of seconds for the random test-mode connection delay. Default is 15 (seconds). | -| `--timeout` | Use to specify the maximum amount of time to wait in seconds for a certificate to be processed by VaaS. Default is 120 (seconds). | -| `--trust-bundle` | Use to specify a file with PEM formatted certificates to be used as trust anchors when communicating with VaaS. Generally not needed because VaaS is secured by a publicly trusted certificate but it may be needed if your organization requires VCert to traverse a proxy server. VCert uses the trust store of your operating system for this purpose if not specified.
Example: `--trust-bundle /path-to/bundle.pem` | -| `-u` | Use to specify the URL of the Venafi as a Service API server. If it's omitted, then VCert will use [https://api.venafi.cloud](https://api.venafi.cloud/vaas) as API server.
Example: `-u https://api.venafi.eu` | -| `--verbose` | Use to increase the level of logging detail, which is helpful when troubleshooting issues. | +| Flag | Description | +|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `--config` | Use to specify INI configuration file containing connection details. Available parameters: `cloud_apikey`, `cloud_zone`, `trust_bundle`, `test_mode`. | +| `-k` or `--apiKey` | Use to specify your API key for Venafi as a Service.
Example: -k aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee | +| `--no-prompt` | Use to exclude password prompts. If you enable the prompt and you enter incorrect information, an error is displayed. This option is useful with scripting. | +| `-p` or `--platform` | Use to specify Venafi as a Service as the platform of choice to connect. Accepted values are: `TLSPC` and `VAAS`. | +| `-t` or `--token` | Use to specify an access token for Venafi as a Service. You need to set `--platform TLSPC` in order to use access tokens for Venafi as a Service. | +| `--test-mode` | Use to test operations without connecting to Venafi as a Service. This option is useful for integration tests where the test environment does not have access to Venafi as a Service. Default is false. | +| `--test-mode-delay` | Use to specify the maximum number of seconds for the random test-mode connection delay. Default is 15 (seconds). | +| `--timeout` | Use to specify the maximum amount of time to wait in seconds for a certificate to be processed by VaaS. Default is 120 (seconds). | +| `--trust-bundle` | Use to specify a file with PEM formatted certificates to be used as trust anchors when communicating with VaaS. Generally not needed because VaaS is secured by a publicly trusted certificate but it may be needed if your organization requires VCert to traverse a proxy server. VCert uses the trust store of your operating system for this purpose if not specified.
Example: `--trust-bundle /path-to/bundle.pem` | +| `-u` or `--url` | Use to specify the URL of the Venafi as a Service API server. If it's omitted, then VCert will use [https://api.venafi.cloud](https://api.venafi.cloud/vaas) as API server.
Example: `-u https://api.venafi.eu` | +| `--verbose` | Use to increase the level of logging detail, which is helpful when troubleshooting issues. | ### Environment Variables -As an alternative to specifying API key, trust bundle, and/or zone via the command line or in a config file, VCert supports supplying those values using environment variables `VCERT_APIKEY`, `VCERT_TRUST_BUNDLE`, `VCERT_URL` and `VCERT_ZONE` respectively. +VCert supports supplying flag values using environment variables: + +| Attribute | Flag | Environment Variable | +|----------------------------|--------------------|----------------------| +| API key | `-k` or `--apiKey` | `VCERT_APIKEY` | +| JWT from Identity Provider | `external-jwt` | `VCERT_EXTERNAL_JWT` | +| Venafi platform | `--platform` | `VCERT_PLATFORM` | +| Tenant ID | `--tenant-id` | `VCERT_TENANT_ID` | +| Venafi as a Service token | `-t` or `--token` | `VCERT_TOKEN` | +| Venafi as a Service URL | `-u` or `--url` | `VCERT_URL` | +| Zone | `-z` or `--zone` | `VCERT_ZONE` | ## Certificate Request Parameters +API key: ``` vcert enroll -k --cn -z ``` +Access token: +``` +vcert enroll -p TLSPC -t --cn -z +``` Options: |         Command         | Description | @@ -120,9 +139,14 @@ Options: | `-z` | Use to specify the name of the Application to which the certificate will be assigned and the API Alias of the Issuing Template that will handle the certificate request.
Example: `-z "Business App\\Enterprise CIT"` | ## Certificate Retrieval Parameters +API key: ``` vcert pickup -k [--pickup-id | --pickup-id-file ] ``` +Access token: +``` +vcert pickup -p TLSPC -t [--pickup-id | --pickup-id-file ] +``` Options: |         Command         | Description | @@ -135,11 +159,15 @@ Options: | `--pickup-id` | Use to specify the unique identifier of the certificate returned by the enroll or renew actions if `--no-pickup` was used or a timeout occurred. Required when `--pickup-id-file` is not specified. | | `--pickup-id-file` | Use to specify a file name that contains the unique identifier of the certificate returned by the enroll or renew actions if --no-pickup was used or a timeout occurred. Required when `--pickup-id` is not specified. | - ## Certificate Renewal Parameters +API key: ``` vcert renew -k [--id | --thumbprint ] ``` +Access token: +``` +vcert renew -p TLSPC -t [--id | --thumbprint ] +``` Options: |         Command         | Description | @@ -168,12 +196,15 @@ Options: | `--san-uri` | Use to specify a Uniform Resource Indicator Subject Alternative Name. To specify more than one, simply repeat this parameter for each value.
Example: `--san-uri spiffe://workload1.example.com` `--san-uri spiffe://workload2.example.com` | | `--thumbprint` | Use to specify the SHA1 thumbprint of the certificate to renew. Value may be specified as a string or read from the certificate file using the `file:` prefix. | - - ## Certificate Retire Parameters +API key: ``` vcert retire -k [--id | --thumbprint ] ``` +Access Token: +``` +vcert retire -p TLSPC -t [--id | --thumbprint ] +``` Options: |         Command         | Description | @@ -182,9 +213,14 @@ Options: | `--thumbprint` | Use to specify the SHA1 thumbprint of the certificate to retire. Value may be specified as a string or read from the certificate file using the `file:` prefix. | ## Parameters for Applying Certificate Policy +API key: ``` vcert setpolicy -k -z --file ``` +Access token: +``` +vcert setpolicy -p TLSPC -t -z --file +``` Options: |         Command         | Description | @@ -206,11 +242,15 @@ When not present in the policy specification, `certificateAuthority` defaults to - The `ipAllowed`, `emailAllowed`, `uriAllowed`, and `upnAllowed` policy (`subjectAltNames`) do not apply as those SAN types are not yet supported by VaaS. - If undefined key/value pairs are included in the policy specification, they will be silently ignored by this action. This would include keys that are misspelled. - ## Parameters for Viewing Certificate Policy +API key: ``` vcert getpolicy -k -z [--file ] ``` +Access token: +``` +vcert getpolicy -p TLSPC -t -z [--file ] +``` Options: |         Command         | Description | @@ -218,7 +258,6 @@ Options: | `--file` | Use to write the retrieved certificate policy to a file in JSON format. If not specified, policy is written to STDOUT. | | `--starter` | Use to generate a template policy specification to help with getting started. `-k` and `-z` are ignored with this option. | - ## Examples For the purposes of the following examples, assume the following: @@ -295,6 +334,17 @@ Options: | `--format` | Specify "json" to get more verbose JSON formatted output instead of the plain text default. | | `--password` | Use to specify the user's password if it is expected the user will need to login to the [Venafi as a Service web UI](https://ui.venafi.cloud/). | +### Obtaining an access token from service account +``` +vcert getcred --platform TLSPC --tenant-id 3dfcc6dc-7309-4dcf-aa7c-5d7a2ee368b4 --external-jwt "file:jwt.txt" +``` +Options: + +| Flag | Description | +|----------------------|-------------------------------------------------------------------------------------------------------------------| +| `-p` or `--platform` | Use to specify Venafi as a Service as the platform of choice to connect. Accepted values are: `TLSPC` and `VAAS`. | +| `--tenant-id` | The ID of the tenant (company) that VCert is connecting to | +| `--external-jwt` | The JWT of the Identity Provider associated to the service account that is going to grant the access token | ### Generating a new key pair and CSR ``` diff --git a/README-PLAYBOOK.md b/README-PLAYBOOK.md index 22fd61bd..58b00266 100644 --- a/README-PLAYBOOK.md +++ b/README-PLAYBOOK.md @@ -90,26 +90,28 @@ The top-level structure of the file is described as follows: ### Connection -| Field | Type | TLSPDC | TLSPC | FIREFLY | Description | -|-------------|------------------------------------|----------------|----------------|----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| credentials | [Credentials](#credentials) object | ***Required*** | ***Required*** | ***Required*** | A [Credential](#credentials) object that defines the credentials used to authenticate to the selected provider `platform`. | -| platform | string | ***Required*** | ***Required*** | ***Required*** | For TLS Protect Datacenter, either `tpp` or `tlspdc`.
For TLS Protect Cloud, either `vaas` or `tlspc`.
For Firefly, use `firefly`. | -| trustBundle | string | *Optional* | n/a | *Optional* | Used when [Connection.platform](#connection) is `tlspdc` or `firefly`.
Defines path to PEM-formatted trust bundle that contains the root (and optionally intermediate certificates) to use to trust the TLS connection. If omitted, will attempt to use operating system trusted CAs. | +| Field | Type | TLSPDC | TLSPC | FIREFLY | Description | +|-------------|------------------------------------|----------------|----------------|----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| credentials | [Credentials](#credentials) object | ***Required*** | ***Required*** | ***Required*** | A [Credential](#credentials) object that defines the credentials used to authenticate to the selected provider `platform`. | +| platform | string | ***Required*** | ***Required*** | ***Required*** | For TLS Protect Datacenter, either `tpp` or `tlspdc`.
For TLS Protect Cloud, either `vaas` or `tlspc`.
For Firefly, use `firefly`. | +| trustBundle | string | *Optional* | n/a | *Optional* | Used when [Connection.platform](#connection) is `tlspdc` or `firefly`.
Defines path to PEM-formatted trust bundle that contains the root (and optionally intermediate certificates) to use to trust the TLS connection. If omitted, will attempt to use operating system trusted CAs. | | url | string | ***Required*** | *Optional* | ***Required*** | URL of the Venafi platform to connect to.
If url string does not include `https://`, it will be added automatically.
For connection to TLS Protect Datacenter, `url` must include the full API path (for example `https://tpp.company.com/vedsdk/`
For TLS Protect Cloud you can specify the url using this parameter https://api.venafi.cloud (US region) or https://api.venafi.eu (EU region).
If not set, will default to US region. | ### Credentials | Field | Type | TLSPDC | TLSPC | FIREFLY | Description | |--------------|--------|----------------|----------------|------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| accessToken | string | *Optional* | n/a | n/a | Used when [Connection.platform](#connection) is `tlspdc` for authenticating to the REST API.
If omitted, invalid, or expired, vcert will attempt to use the [Credential.p12Task](#credentials) or [Credential.refreshToken](#credentials) to get a valid accessToken.
Upon successful refresh, this value will be overwritten with the new valid accessToken. | +| accessToken | string | *Optional* | *Optional* | n/a | Used when [Connection.platform](#connection) is `tlspdc` for authenticating to the REST API.
If omitted, invalid, or expired, vcert will attempt to use the [Credential.p12Task](#credentials) or [Credential.refreshToken](#credentials) to get a valid accessToken.
Upon successful refresh, this value will be overwritten with the new valid accessToken. | | apiKey | string | n/a | ***Required*** | n/a | Used when [Connection.platform](#connection) is `tlspc` for authenticating to the REST API. | | audience | string | n/a | n/a | *Optional* | Used when [Connection.platform](#connection) is `firefly` to map the audience for the authorization token request from the OAuth2 Provider. Not all OAuth2 providers require this value. | | clientId | string | *Optional* | n/a | *Optional* | Used when [Connection.platform](#connection) is `tlspc` to map to the API integration to be used. If omitted, uses `vcert-sdk` as default.

Used when [Connection.platform](#connection) is `firefly` along with `clientSecret` to follow a `credentials authorization flow`. | | clientSecret | string | n/a | n/a | *Optional* | Used when [Connection.platform](#connection) is `firefly` along with `clientId` to follow a `credentials authorization flow` to get an authorization token from the OAuth2 Provider. | + | externalJWT | string | n/a | *Optional* | n/a | Used when [Connection.platform](#connection) is `tlspc` along with `tenantId` to request a new authorization token from a service account. | | p12Task | string | *Optional* | n/a | n/a | Used when [Connection.platform](#connection) is `tlspdc` to reference a configured [CertificateTasks.name](#certificatetask) to be used for certificate authentication.
Will be used to get a new accessToken when `accessToken` is missing, invalid, or expired.
Referenced `certificateTask` must have an installation of type `pkcs12`. | | password | string | n/a | n/a | *Optional* | Used when [Connection.platform](#connection) is `firefly` along with `user` to follow a `password authorization flow` to request a new authorization token from the OAuth2 Provider. | | refreshToken | string | *Optional* | n/a | n/a | Used when [Connection.platform](#connection) is `tlspdc` to refresh the `accessToken` if it is missing, invalid, or expired.
If omitted, the `accessToken` will not be refreshed when it expires.
When a refresh token is used, a new accessToken *and* refreshToken are issued and the previous refreshToken is then invalid (one-time use only).
vCert will attempt to update the refreshToken and accessToken fields upon refresh. | | scope | string | *Optional* | n/a | *Optional* | Used when [Connection.platform](#connection) is `tlspdc` to determine the scope of the token when refreshing the access token, or when getting a new grant using a `pkcs12` certificate. Defaults to `certificate:manage` if omitted.

Used when [Connection.platform](#connection) is `firefly` to determine the scope of the token to be requested to the OAuth2 provider. Some providers may have default scopes while others dont. | + | tenantId | string | n/a | *Optional* | n/a | Used when [Connection.platform](#connection) is `tlspc` along with `externalJWT` to request a new authorization token from a service account. | | tokenURL | string | ***Required*** | n/a | n/a | Used when [Connection.platform](#connection) is `firefly` to request a new authorization token to the OAuth2 Provider. | | user | string | n/a | n/a | *Optional* | Used when [Connection.platform](#connection) is `firefly` along with `password` to follow a `password` authorization flow to request a new authorization token from the OAuth2 Provider. | diff --git a/README.md b/README.md index be046de7..9c67fe25 100644 --- a/README.md +++ b/README.md @@ -33,14 +33,14 @@ Custom Fields and Instance Tracking require TPP 18.2 or higher, and Token Authen 3. Download the source code: ```sh -go get github.com/Venafi/vcert/v4 +go get github.com/Venafi/vcert/v5 ``` or Pre Go 1.13 ```sh -git clone https://github.com/Venafi/vcert.git $GOPATH/src/github.com/Venafi/vcert/v4 +git clone https://github.com/Venafi/vcert.git $GOPATH/src/github.com/Venafi/vcert/v5 ``` Go 1.11 with go modules enabled or go 1.13 and up make sure to clone outside of `$GOPATH/src` @@ -56,11 +56,11 @@ make build ## Using VCert to integrate Venafi with your application -For code samples of programmatic use, please review the files in [/examples](/examples/). +For code samples of programmatic use, please review the files in [examples folder](./examples). ### Common part -1. In your main.go file, make the following import declarations: `github.com/Venafi/vcert/v4`, `github.com/Venafi/vcert/v4/pkg/certificate`, and `github.com/Venafi/vcert/v4/pkg/endpoint`. -1. Create a configuration object of type `&vcert.Config` that specifies the Venafi connection details. Solutions are typically designed to get those details from a secrets vault, .ini file, environment variables, or command line parameters. +1. In your main.go file, make the following import declarations: `github.com/Venafi/vcert/v5`, `github.com/Venafi/vcert/v5/pkg/certificate`, and `github.com/Venafi/vcert/v5/pkg/endpoint`. +2. Create a configuration object of type `&vcert.Config` that specifies the Venafi connection details. Solutions are typically designed to get those details from a secrets vault, .ini file, environment variables, or command line parameters. ### Enroll certificate 1. Instantiate a client by calling the `NewClient` method of the vcert class with the configuration object.