Skip to content

Commit

Permalink
Merge pull request #874 from hashicorp/feature/generic-oidc-auth
Browse files Browse the repository at this point in the history
Support for generic OIDC providers
  • Loading branch information
manicminer authored Aug 25, 2022
2 parents 1a04a24 + bb76df6 commit fcefcbc
Show file tree
Hide file tree
Showing 12 changed files with 540 additions and 26 deletions.
12 changes: 9 additions & 3 deletions docs/guides/service_principal_oidc.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ We recommend using either a Service Principal or Managed Identity when running T

Once you have configured a Service Principal as described in this guide, you should follow the [Configuring a Service Principal for managing Azure Active Directory](service_principal_configuration.html) guide to grant the Service Principal necessary permissions to create and modify Azure Active Directory objects such as users and groups.

~> **Note:** The current implementation of OIDC authentication currently only works in GitHub actions.

---

## Setting up an Application and Service Principal
Expand Down Expand Up @@ -84,6 +82,12 @@ Where the body is:

See the [official documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/workload-identity-federation-create-trust-github) for more details.

### Configure Azure Active Directory Application to Trust a Generic Issuer

On the Azure Active Directory application page, go to **Certificates and secrets**.

In the Federated credentials tab, select **Add credential**. The 'Add a credential' blade opens. Refer to the instructions from your OIDC provider for completing the form, before choosing a **Name** for the federated credential and clicking the **Add** button.

## Configuring Terraform to use OIDC

~> **Note:** If using the AzureRM Backend you may also need to configure OIDC there too, see [the documentation for the AzureRM Backend](https://www.terraform.io/language/settings/backends/azurerm) for more information.
Expand All @@ -98,7 +102,9 @@ $ export ARM_SUBSCRIPTION_ID="00000000-0000-0000-0000-000000000000"
$ export ARM_TENANT_ID="00000000-0000-0000-0000-000000000000"
```

The provider will detect the `ACTIONS_ID_TOKEN_REQUEST_URL` and `ACTIONS_ID_TOKEN_REQUEST_TOKEN` environment variables set by GitHub. You can also specify the `ARM_OIDC_REQUEST_TOKEN` and `ARM_OIDC_REQUEST_URL` environment variables.
The provider will use the `ARM_OIDC_TOKEN` environment variable as an OIDC token. You can use this variable to specify the token provided by your OIDC provider.

When running in GitHub Actions, the provider will detect the `ACTIONS_ID_TOKEN_REQUEST_URL` and `ACTIONS_ID_TOKEN_REQUEST_TOKEN` environment variables set by the GitHub Actions runtime. You can also specify the `ARM_OIDC_REQUEST_TOKEN` and `ARM_OIDC_REQUEST_URL` environment variables.

For GitHub Actions workflows, you'll need to ensure the workflow has `write` permissions for the `id-token`.

Expand Down
3 changes: 1 addition & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,8 @@ More information on [how to configure a Service Principal using a Client Secret
When authenticating as a Service Principal using Open ID Connect, the following fields can be set:

* `oidc_request_token` - (Optional) The bearer token for the request to the OIDC provider. This can also be sourced from the `ARM_OIDC_REQUEST_TOKEN` or `ACTIONS_ID_TOKEN_REQUEST_TOKEN` Environment Variables.

* `oidc_request_url` - (Optional) The URL for the OIDC provider from which to request an ID token. This can also be sourced from the `ARM_OIDC_REQUEST_URL` or `ACTIONS_ID_TOKEN_REQUEST_TOKEN` Environment Variables.

* `oidc_token` - (Optional) The ID token when authenticating using OpenID Connect (OIDC). This can also be sourced from the `ARM_OIDC_TOKEN` environment Variable.
* `use_oidc` - (Optional) Should OIDC be used for Authentication? This can also be sourced from the `ARM_USE_OIDC` Environment Variable. Defaults to `false`.

More information on [how to configure a Service Principal using OpenID Connect can be found in this guide](guides/service_principal_oidc.html).
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ require (
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
github.com/hashicorp/go-uuid v1.0.3
github.com/hashicorp/terraform-plugin-sdk/v2 v2.17.0
github.com/manicminer/hamilton v0.46.0
github.com/manicminer/hamilton v0.47.0
golang.org/x/text v0.3.7
)

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/manicminer/hamilton v0.46.0 h1:ag0xqWnALt9uQSfrrrXuQvm6puV8y+LghJQD32lzW+M=
github.com/manicminer/hamilton v0.46.0/go.mod h1:lbVyngC+/nCWuDp8UhC6Bw+bh7jcP/E+YwqzHTmzemk=
github.com/manicminer/hamilton v0.47.0 h1:k7IiugZ2gL9OrX59OSNQ9Kld4Nl3xG8wh3VP5ltGtO0=
github.com/manicminer/hamilton v0.47.0/go.mod h1:lbVyngC+/nCWuDp8UhC6Bw+bh7jcP/E+YwqzHTmzemk=
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
Expand Down
39 changes: 24 additions & 15 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ func AzureADProvider() *schema.Provider {
Description: "Allow OpenID Connect to be used for authentication",
},

"oidc_token": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("ARM_OIDC_TOKEN", ""),
Description: "The ID token for use when authenticating as a Service Principal using OpenID Connect.",
},

"oidc_request_token": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -212,21 +219,23 @@ func providerConfigure(p *schema.Provider) schema.ConfigureContextFunc {
}

authConfig := &auth.Config{
Environment: env,
TenantID: d.Get("tenant_id").(string),
ClientID: d.Get("client_id").(string),
ClientCertData: certData,
ClientCertPassword: d.Get("client_certificate_password").(string),
ClientCertPath: d.Get("client_certificate_path").(string),
ClientSecret: d.Get("client_secret").(string),
IDTokenRequestURL: d.Get("oidc_request_url").(string),
IDTokenRequestToken: d.Get("oidc_request_token").(string),
EnableClientCertAuth: true,
EnableClientSecretAuth: true,
EnableGitHubOIDCAuth: d.Get("use_oidc").(bool),
EnableAzureCliToken: d.Get("use_cli").(bool),
EnableMsiAuth: d.Get("use_msi").(bool),
MsiEndpoint: d.Get("msi_endpoint").(string),
Environment: env,
TenantID: d.Get("tenant_id").(string),
ClientID: d.Get("client_id").(string),
ClientCertData: certData,
ClientCertPassword: d.Get("client_certificate_password").(string),
ClientCertPath: d.Get("client_certificate_path").(string),
ClientSecret: d.Get("client_secret").(string),
FederatedAssertion: d.Get("oidc_token").(string),
IDTokenRequestURL: d.Get("oidc_request_url").(string),
IDTokenRequestToken: d.Get("oidc_request_token").(string),
EnableClientCertAuth: true,
EnableClientSecretAuth: true,
EnableClientFederatedAuth: d.Get("use_oidc").(bool),
EnableGitHubOIDCAuth: d.Get("use_oidc").(bool),
EnableAzureCliToken: d.Get("use_cli").(bool),
EnableMsiAuth: d.Get("use_msi").(bool),
MsiEndpoint: d.Get("msi_endpoint").(string),
}

// only one pid can be interpreted currently
Expand Down
42 changes: 41 additions & 1 deletion internal/provider/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,47 @@ func TestAccProvider_clientSecretAuth(t *testing.T) {
}
}

func TestAccProvider_oidcAuth(t *testing.T) {
func TestAccProvider_genericOidcAuth(t *testing.T) {
if os.Getenv("TF_ACC") == "" {
return
}

provider := AzureADProvider()
ctx := context.Background()

// Support only oidc authentication
provider.ConfigureContextFunc = func(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
envName := d.Get("environment").(string)
env, err := environments.EnvironmentFromString(envName)
if err != nil {
t.Fatalf("configuring environment %q: %v", envName, err)
}

authConfig := &auth.Config{
Environment: env,
TenantID: d.Get("tenant_id").(string),
ClientID: d.Get("client_id").(string),

EnableClientFederatedAuth: true,
FederatedAssertion: d.Get("oidc_token").(string),
}

return buildClient(ctx, provider, authConfig, "")
}

d := provider.Configure(ctx, terraform.NewResourceConfigRaw(nil))
if d != nil && d.HasError() {
t.Fatalf("err: %+v", d)
}

if errs := testCheckProvider(provider); len(errs) > 0 {
for _, err := range errs {
t.Error(err)
}
}
}

func TestAccProvider_githubOidcAuth(t *testing.T) {
if os.Getenv("TF_ACC") == "" {
return
}
Expand Down
26 changes: 26 additions & 0 deletions vendor/github.com/manicminer/hamilton/auth/auth.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions vendor/github.com/manicminer/hamilton/auth/config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

91 changes: 91 additions & 0 deletions vendor/github.com/manicminer/hamilton/msgraph/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit fcefcbc

Please sign in to comment.