hashicorp / terraform-provider-azuread

Terraform provider for Azure Active Directory
https://registry.terraform.io/providers/hashicorp/azuread/latest/docs
Mozilla Public License 2.0
423 stars 289 forks source link

Export OIDC issuer URL as attribute of azuread_application #1279

Open sym-stiller opened 9 months ago

sym-stiller commented 9 months ago

Community Note

Description

To configure login via OIDC at various systems, i need to know the URL of the OIDC issuer. This URL is stored in the JWTs issued by Entra ID as the iss claim and will be validated by the system I want to authenticate at.

In most of my use cases, this URL can be terraformed like this: https://login.microsoftonline.com/${data.azurerm_client_config.current.tenant_id}/, but in some cases the OIDC issuer URL might be different (e.g. when using v1 tokens, the URL might be something like https://sts.windows.net/${data.azurerm_client_config.current.tenant_id}/). It would be great if the azuread_application resource could provide an attribute that I can use instead of my hardcoded, hand-crafted string.

An example of how this attribute could be implemented can be found in the AzureRM provider; the azurerm_kubernetes_cluster resource exports an attribute called oidc_issuer_url which I can directly use to configure e.g. federated credentials for Workload Identity.

New or Affected Resource(s)

azuread_application

Potential Terraform Configuration

To make my use case clearer, I am providing an example where I try to configure the boundary_auth_method_oidc resource from the hashicorp/boundary provider using attributes from azuread_application.

variable "boundary_url" {
  type = string
}

resource "azuread_application" "boundary_oid_auth" {
  display_name = "Boundary (OIDC auth)"

  group_membership_claims = ["All"]

  required_resource_access {
    resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph

    resource_access {
      id   = "df021288-bdef-4463-88db-98f22de89214" # User.Read.All
      type = "Role"
    }

    resource_access {
      id   = "b4e74841-8e56-480b-be8b-910348b18b4c" # User.ReadWrite
      type = "Scope"
    }

    resource_access {
      id   = "98830695-27a2-44f7-8c18-0c3ebc9698f6" # GroupMember.Read.All
      type = "Role"
    }
  }

  web {
    logout_url    = "${var.boundary_url}:3000"
    redirect_uris = ["${var.boundary_url}/v1/auth-methods/oidc:authenticate:callback"]
  }
}

resource "azuread_application_password" "boundary_oidc_auth" {
  application_id = azuread_application.boundary_oidc_auth.id
  display_name   = "Boundary (OIDC auth) client secret"
}

resource "azuread_service_principal" "boundary_oidc_auth" {
  client_id = azuread_application.boundary_oidc_auth.client_id
}

resource "boundary_auth_method_oidc" "entra_id" {
  # Using the new property from azuread_application instead of hardcoding it
  issuer             = azuread_application.boundary_oidc_auth.oidc_issuer_url

  name               = "Microsoft Entra ID"
  description        = "OIDC auth method using Microsoft Entra ID"
  scope_id           = "global"
  client_id          = azuread_application.boundary_oidc_auth.client_id
  client_secret      = azuread_application_password.boundary_oidc_auth.value
  signing_algorithms = ["RS256"]
  api_url_prefix     = var.boundary_url
}

References

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/kubernetes_cluster#oidc_issuer_url

nbaju1 commented 8 months ago

I don't believe there is an endpoint to fetch this URL. And I also believe that (as of now at least) it's either https://login.microsoftonline.com/<tenant-id> for v2 tokens or https://sts.windows.net/<tenant-id> for v1 tokens. So you could do something like:


variable "boundary_url" {
  type = string
}

data "azuread_client_config" "current" {}

resource "azuread_application" "boundary_oid_auth" {
  display_name = "Boundary (OIDC auth)"

...
  api {
    requested_access_token_version = 2
}

resource "azuread_application_password" "boundary_oidc_auth" {
  application_id = azuread_application.boundary_oidc_auth.id
  display_name   = "Boundary (OIDC auth) client secret"
}

resource "boundary_auth_method_oidc" "entra_id" {
  issuer             = (azuread_application.boundary_oid_auth.api.requested_access_token_version == 1 ? 
  "https://sts.windows.net/${data.azuread_client_config.current.tenant_id}/" : 
  "https://login.microsoftonline.com/${data.azuread_client_config.current.tenant_id}/")

  name               = "Microsoft Entra ID"
  description        = "OIDC auth method using Microsoft Entra ID"
  scope_id           = "global"
  client_id          = azuread_application.boundary_oidc_auth.client_id
  client_secret      = azuread_application_password.boundary_oidc_auth.value
  signing_algorithms = ["RS256"]
  api_url_prefix     = var.boundary_url
}