pulumi-azuread icon indicating copy to clipboard operation
pulumi-azuread copied to clipboard

Missing subscriptionId for authentication via Service Principal

Open ericdonggraphite opened this issue 1 year ago • 13 comments

What happened?

I am trying to create an app registration in azure with the azuread provider. My stack is able to run without issues when authenticating via az login. However, when I try to authenticate via service principal I get the following error: * A Subscription ID must be configured when authenticating as a Service Principal using a Client Secret.. I added the subscription ID to my pulumi config like so azuread:subscriptionId: aaaabbbb-abba-aaaa-bbbb-aaa111bbbbb. I then get the following error: could not validate provider configuration: 1 error occurred: * Invalid or unknown key. It seems like the azuread provider is missing the subscriptionId key to properly authenticate via service principal.

Example

My pulumi code below:

import pulumi
import pulumi_azuread as azuread


app_registation = azuread.Application(
            f"my app reg",
            api=azuread.ApplicationApiArgs(
                oauth2_permission_scopes=[],
            ),
            display_name=f"my app reg",
            owners=[
                "<user ID>",
            ],
            required_resource_accesses=[
                azuread.ApplicationRequiredResourceAccessArgs(
                    resource_accesses=[
                        azuread.ApplicationRequiredResourceAccessResourceAccessArgs(
                            id="e1fe6dd8-ba31-4d61-89e7-88639da4683d",
                            type="Scope",
                        ),
                    ],
                    resource_app_id="00000003-0000-0000-c000-000000000000",
                )
            ],
            single_page_application=azuread.ApplicationSinglePageApplicationArgs(
                redirect_uris=[
                "http://localhost:8008/",
            ],
            ),
            sign_in_audience="AzureADMyOrg",
            web=azuread.ApplicationWebArgs(
                homepage_url="http://localhost:8008",
                implicit_grant=azuread.ApplicationWebImplicitGrantArgs(
                    access_token_issuance_enabled=True,
                    id_token_issuance_enabled=True,
                ),
            ),
        )

This config below produces the following error:

error: failed to load application credentials.
    Details: 1 error occurred:
        * A Subscription ID must be configured when authenticating as a Service Principal using a Client Secret.
config:
  azuread:clientId: <service principal client ID>
  azuread:clientSecret:
    secure: <service principal client secret>
  azuread:tenantId: <service principal tenant ID>

This config below produces the following error:

    error: could not validate provider configuration: 1 error occurred:
        * Invalid or unknown key
config:
  azuread:clientId: <service principal client ID>
  azuread:clientSecret:
    secure: <service principal client secret>
  azuread:tenantId: <service principal tenant ID>
  azuread:subscriptionId: <service principal subscription ID>

Output of pulumi about

CLI          
Version      3.108.1
Go Version   go1.22.0
Go Compiler  gc

Plugins
NAME          VERSION
azure-native  2.33.0
azuread       5.47.2
kubernetes    3.30.2
python        unknown
random        4.16.0
tls           4.11.1

Host     
OS       darwin
Version  14.3.1
Arch     arm64

This project is written in python: executable

Dependencies:
NAME                 VERSION
pip                  24.0
pulumi_azure_native  2.33.0
pulumi_azuread       5.47.2
pulumi_kubernetes    3.30.2
pulumi_random        4.16.0
pulumi-tls           4.11.1
setuptools           69.2.0
typing_extensions    4.10.0
wheel                0.43.0

Additional context

No response

Contributing

Vote on this issue by adding a 👍 reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

ericdonggraphite avatar Mar 28 '24 15:03 ericdonggraphite

Hi @ericdonggraphite thanks for raising this. When using OIDC, I think the Subscription ID must be set via an environment variable (ARM_SUBSCRIPTION_ID).

Please could you confirm if this resolves the issue?

It looks like this detail is currently missing from the docs page on configuration so we'll keep this issue open to track this.

danielrbradley avatar Apr 02 '24 10:04 danielrbradley

Hi Daniel, setting the ARM_SUBSCRIPTION_ID env var works, however I am trying to avoid this because it makes deployments more difficult for us and each developer would have to set this variable in this local stack to run Pulumi. Is there a way to programmatically set the env vars when I run pulumi up -y so that no additional shell commands needed to be run for the stack to provision?

ericdonggraphite avatar Apr 03 '24 15:04 ericdonggraphite

Sure, your best way to manage environment variables between users is to use Pulumi ESC environments to automatically set this variable.

danielrbradley avatar Apr 04 '24 20:04 danielrbradley

@danielrbradley @thomas11 I'm curious - why don't we allow setting subscriptionId via config?

mikhailshilkov avatar Apr 17 '24 08:04 mikhailshilkov

@danielrbradley @thomas11 I'm curious - why don't we allow setting subscriptionId via config?

I don't know, and I think we could allow it. I have a little side-project documenting the inconsistencies between Azure providers and this one came up. I'll try give it a shot soon-ish.

thomas11 avatar Apr 17 '24 09:04 thomas11

@mikhailshilkov I think this is implemented in the upstream provider. I don't know why it's not been exposed as configuration too.

Perhaps it was thought that if you're authenticating via service principal then you'll be scoped to a single subscription, so it's simpler to be a single environment variable, or perhaps the effort of plumbing it via configuration was a bit tricky.

danielrbradley avatar Apr 17 '24 10:04 danielrbradley

It sounds like we should add it!

mikhailshilkov avatar Apr 18 '24 09:04 mikhailshilkov

On further research, it turns out that subscription ids were actually completely removed from the upstream Terraform azuread provider. The reasoning being that Entra ID is not subscription-based, and every operation requiring a subscription belongs into the Azure provider.

In fact, the version of the auth package that azuread uses doesn't contain the error message you're seeing.

This made me dig down deeper as to where the error actually comes from, and I think the explanation is a different one: the error isn't coming from the Pulumi azuread provider, but from the Pulumi Azure provider which your program also uses:

Plugins
NAME          VERSION
azure-native  2.33.0

This provider depends on an older version of the auth package for compatibility reasons, and that version contains the error "must be configured when authenticating as a Service Principal".

So, to get around the error, you could

  • remove the azure-native dependency if you're not using it
  • set config azure-native:subscriptionId

Please let me know if this helped.

thomas11 avatar Apr 22 '24 08:04 thomas11

We use azure-native heavily without any issues. We have set the following configs for azure-native and never had authentication issues via Service Principal with this package. It was only after we started using azuread where we saw this issue with the subscriptionId. azure-native:clientId: azure-native:clientSecret: azure-native:location azure-native:subscriptionId: azure-native:tenantId:

ericdonggraphite avatar Apr 22 '24 16:04 ericdonggraphite

I see. Would you be able to capture verbose logs according to this guide? Thank you!

thomas11 avatar Apr 22 '24 19:04 thomas11

I am not comfortable with sharing verbose logs that contain subscription ids and names of my Azure resources. Is there a way to filter out these sensitive info from the logs? We actually removed all azuread dependencies from our pulumi code due to this issue so you may close the issue if you choose to. However, if the auth issue gets solved it would clean up our code quite a bit. Thanks for all the help!

ericdonggraphite avatar Apr 24 '24 19:04 ericdonggraphite

I'm sorry we couldn't find a solution yet. I was able to confirm that with a minimal pulumi-azuread program, no azure native involved, everything works fine without a subscription id and without ARM_SUBSCRIPTION_ID. That doesn't tell us yet what the problem is, unfortunately.

thomas11 avatar Apr 26 '24 10:04 thomas11

Adding azure-native to the azuread program, everything still works.

The complete program is

package main

import (
	"github.com/pulumi/pulumi-azure-native-sdk/resources/v2"
	azad "github.com/pulumi/pulumi-azuread/sdk/v5/go/azuread"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := resources.NewResourceGroup(ctx, "my-rg", &resources.ResourceGroupArgs{})
		if err != nil {
			return err
		}

		_, err = azad.NewGroup(ctx, "my-group", &azad.GroupArgs{
			DisplayName:     pulumi.String("my-group"),
			SecurityEnabled: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}

		return nil
	})
}

and its config is

❯ pulumi config | awk '{ print $1 }'
KEY
azure-native:clientId
azure-native:clientSecret
azure-native:location
azure-native:subscriptionId
azure-native:tenantId
azuread:clientId
azuread:clientSecret
azuread:tenantId

with ARM_SUBSCRIPTION_ID not set.

It seems to me that the involvement of azuread was a red herring and the error came from azure-native. Although you said the azure-native program worked fine after you removed azuread? With identical config and auth method? If so, then I don't know what's happening here.

thomas11 avatar Apr 26 '24 14:04 thomas11

Since the upstream provider doesn't support subscriptions and the issue with the azure-native interaction couldn't be reproduced, I'll close this issue. Feel free to re-open if necessary.

thomas11 avatar Jul 17 '24 07:07 thomas11