From 2b320f4ec3af3b46dd361e558395ea119ec2c7a0 Mon Sep 17 00:00:00 2001 From: mawasile <50197777+mawasile@users.noreply.github.com> Date: Thu, 11 Jul 2024 18:33:25 +0200 Subject: [PATCH] Add certificate based authentication for the provider (#352) * adding cert based auth * Update index.md.tmpl for typo --------- Co-authored-by: Matt Dotson --- docs/index.md | 52 +++++++- .../powerplatform_environments/cert.pkcs12 | Bin 0 -> 4435 bytes go.mod | 1 + go.sum | 2 + internal/powerplatform/api/auth.go | 33 +++++- internal/powerplatform/config/config.go | 39 +++--- internal/powerplatform/helpers/cert.go | 75 ++++++++++++ internal/powerplatform/provider.go | 111 +++++++++++++----- templates/index.md.tmpl | 54 ++++++++- 9 files changed, 316 insertions(+), 51 deletions(-) create mode 100644 examples/data-sources/powerplatform_environments/cert.pkcs12 create mode 100644 internal/powerplatform/helpers/cert.go diff --git a/docs/index.md b/docs/index.md index b35103583..b4cd1d3f9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -84,6 +84,7 @@ provider "powerplatform" { ``` Additional Resources about OIDC: + * [OpenID Connect authentication with Microsoft Entra ID](https://learn.microsoft.com/entra/architecture/auth-oidc) * [Configuring OpenID Connect for GitHub and Microsoft Entra ID](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-azure) @@ -95,6 +96,49 @@ The Power Platform provider can use a Service Principal with Client Secret to au 1. [Register your app registration with Power Platform](https://learn.microsoft.com/power-platform/admin/powerplatform-api-create-service-principal#registering-an-admin-management-application) 1. Configure the provider to use a Service Principal with a Client Secret with either environment variables or using Terraform variables +### Authenticating to Power Platfomr using Service Principal and certificate + +1. [Create an app registration for the Power Platform Terraform Provider](guides/app_registration.md) +1. [Register your app registration with Power Platform](https://learn.microsoft.com/power-platform/admin/powerplatform-api-create-service-principal#registering-an-admin-management-application) +1. Generate a certificate using openssl or other tools + +```bash +openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 +``` + +4. Merge public and private part of the certificate files together + +Using linux shell + +```bash +cat *.pem > cert+key.pem +``` + +Using Powershell + +```powershell +Get-Content .\cert.pem, .\key.pem | Set-Content cert+key.pem +``` + +5. Generate pkcs12 file + +```bash +openssl pkcs12 -export -out cert.pkcs12 -in cert+key.pem +``` + +6. Add public part of the certificate (`cert.pem` file) to the app registration +7. Store your key.pem and the password used to generate in a safe place +8. Configure the provider to use certificate with the following code: + +```terraform +provider "powerplatform" { + client_id = var.client_id + tenant_id = var.tenant_id + client_certificate_file_path = "${path.cwd}/cert.pkcs12" + client_certificate_password = var.cert_pass +} +``` + #### Using Environment Variables We recomend using Environment Variables to pass the credentials to the provider. @@ -104,12 +148,18 @@ We recomend using Environment Variables to pass the credentials to the provider. | `POWER_PLATFORM_CLIENT_ID` | The service principal client id | | | `POWER_PLATFORM_CLIENT_SECRET` | The service principal secret | | | `POWER_PLATFORM_TENANT_ID` | The guid of the tenant | | +| `POWER_PLATFORM_CLOUD` | override for the cloud used (default is `public`) | | +| `POWER_PLATFORM_USE_OIDC` | if set to `true` then OIDC authentication will be used | | +| `POWER_PLATFORM_USE_CLI` | if set to `true` then Azure CLI authentication will be used | | +| `POWER_PLATFORM_CLIENT_CERTIFICATE` | The Base64 format of your certificate that will be used to certificate based authentication | | +| `POWER_PLATFORM_CLIENT_CERTIFICATE_FILE_PATH` | The path to the certificate that will be used to certificate based authentication | | +| `POWER_PLATFORM_CLIENT_CERTIFICATE_PASSWORD` | Password for the provider certificate | | -> Variables passed into the provider will override the environment variables. #### Using Terraform Variables -Alternatively, you can configure the provider using variables in your Terraform configuration which can be passed in via [command line parameters](https://developer.hashicorp.com/terraform/language/values/variables#variables-on-the-command-line), [a `*.tfvars` file](https://developer.hashicorp.com/terraform/language/values/variables#variable-definitions-tfvars-files), or [environment variables](https://developer.hashicorp.com/terraform/language/values/variables#environment-variables). If you choose to use variables, please be sure to [protect sensitive input variables](https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables) so that you do not expose your credentials in your Terraform configuration. +Alternatively, you can configure the provider using variables in your Terraform configuration which can be passed in via [command line parameters](https://developer.hashicorp.com/terraform/language/values/variables#variables-on-the-command-line), [a `*.tfvars` file](https://developer.hashicorp.com/terraform/language/values/variables#variable-definitions-tfvars-files), or [environment variables](https://developer.hashicorp.com/terraform/language/values/variables#environment-variables). If you choose to use variables, please be sure to [protect sensitive input variables](https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables) so that you do not expose your credentials in your Terraform configuration. ```terraform provider "powerplatform" { diff --git a/examples/data-sources/powerplatform_environments/cert.pkcs12 b/examples/data-sources/powerplatform_environments/cert.pkcs12 new file mode 100644 index 0000000000000000000000000000000000000000..a70a7085a367c888ed51d448092c3b1d46b7a495 GIT binary patch literal 4435 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 J cert+key.pem +``` + +Using Powershell + +```powershell +Get-Content .\cert.pem, .\key.pem | Set-Content cert+key.pem +``` + +5. Generate pkcs12 file + +```bash +openssl pkcs12 -export -out cert.pkcs12 -in cert+key.pem +``` + +6. Add public part of the certificate (`cert.pem` file) to the app registration +7. Store your key.pem and the password used to generate in a safe place +8. Configure the provider to use certificate with the following code: + +```terraform +provider "powerplatform" { + client_id = var.client_id + tenant_id = var.tenant_id + client_certificate_file_path = "${path.cwd}/cert.pkcs12" + client_certificate_password = var.cert_pass +} +``` + #### Using Environment Variables We recomend using Environment Variables to pass the credentials to the provider. @@ -104,12 +148,18 @@ We recomend using Environment Variables to pass the credentials to the provider. | `POWER_PLATFORM_CLIENT_ID` | The service principal client id | | | `POWER_PLATFORM_CLIENT_SECRET` | The service principal secret | | | `POWER_PLATFORM_TENANT_ID` | The guid of the tenant | | +| `POWER_PLATFORM_CLOUD` | override for the cloud used (default is `public`) | | +| `POWER_PLATFORM_USE_OIDC` | if set to `true` then OIDC authentication will be used | | +| `POWER_PLATFORM_USE_CLI` | if set to `true` then Azure CLI authentication will be used | | +| `POWER_PLATFORM_CLIENT_CERTIFICATE` | The Base64 format of your certificate that will be used to certificate based authentication | | +| `POWER_PLATFORM_CLIENT_CERTIFICATE_FILE_PATH` | The path to the certificate that will be used to certificate based authentication | | +| `POWER_PLATFORM_CLIENT_CERTIFICATE_PASSWORD` | Password for the provider certificate | | -> Variables passed into the provider will override the environment variables. #### Using Terraform Variables -Alternatively, you can configure the provider using variables in your Terraform configuration which can be passed in via [command line parameters](https://developer.hashicorp.com/terraform/language/values/variables#variables-on-the-command-line), [a `*.tfvars` file](https://developer.hashicorp.com/terraform/language/values/variables#variable-definitions-tfvars-files), or [environment variables](https://developer.hashicorp.com/terraform/language/values/variables#environment-variables). If you choose to use variables, please be sure to [protect sensitive input variables](https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables) so that you do not expose your credentials in your Terraform configuration. +Alternatively, you can configure the provider using variables in your Terraform configuration which can be passed in via [command line parameters](https://developer.hashicorp.com/terraform/language/values/variables#variables-on-the-command-line), [a `*.tfvars` file](https://developer.hashicorp.com/terraform/language/values/variables#variable-definitions-tfvars-files), or [environment variables](https://developer.hashicorp.com/terraform/language/values/variables#environment-variables). If you choose to use variables, please be sure to [protect sensitive input variables](https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables) so that you do not expose your credentials in your Terraform configuration. ```terraform provider "powerplatform" { @@ -132,7 +182,7 @@ In addition to the authentication options, the following options are also suppor Use the navigation to the left to read about the available resources and data sources. -!> By calling `terraform destroy` all the resources, that you've created, will be deleted permamently deleted. Please be careful with this command when working with production environments. You can use [prevent-destory](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle#prevent_destroy) lifecycle argument in your resources to prevent accidental deletion. +!> By calling `terraform destroy` all the resources, that you've created, will be deleted permamently deleted. Please be careful with this command when working with production environments. You can use [prevent-destroy](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle#prevent_destroy) lifecycle argument in your resources to prevent accidental deletion. ## Examples