Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

/config endpoint causes confusion and imposes limitations due to use of subscription_id field #102

Open
natilik-mikeguy opened this issue Aug 22, 2022 · 5 comments

Comments

@natilik-mikeguy
Copy link

natilik-mikeguy commented Aug 22, 2022

Good evening!

I've been looking at the Azure secrets engine, and for people familiar with Azure I feel it is a little confusing and imposes unnecessary restrictions that hamper functionality and/or increase management overheads. I shall explain below - apologies if I have misunderstood anything.

The Issue

When writing data to /azure/config, you are essentially configuring the details of the service principal that Vault itself will use to authenticate to Azure AD (and generate further service principals). When configuring this in Vault, you MUST provide "subscription_id" for it to work (at least it seems this way from a quick test) - this has the following challenges:

  • To those familiar with Azure, it is confusing. A service principal doesn't "belong" to a subscription. Azure AD has no concept of subscriptions, it just so happens however that Azure AD service principals (and users/groups etc.) are used to grant access to Azure resources. In other words Azure AD != Azure Resources.
  • Confusion aside, this imposes the following limitations:
    • You must configure a new mount point per subscription. You cannot use multiple configurations per mount (as you can with say the database secrets engine). It is not uncommon to see large numbers of subscriptions within Azure - adding management overhead and making the path structure of Vault a little unwieldy in these environments.
    • The dynamic credentials you wish to generate/rotate may not be tied to Azure resources in any way whatsoever (so subscription ID is irrelevant and even more confusing). For example, you may have some application that authenticates to the Microsoft Graph API (with client_id and secret_id) to retrieve user data from Azure AD, but never has any need to perform actions against Azure Resources.

Enhancement Request

Please consider de-coupling the service principal that Vault uses from the subscriptions it may (or may not) manage. i.e. to create a SP it may look like:

vault write azure/config \
     client_id=$CLIENT_ID \
     client_secret=$CLIENT_SECRET \
     tenant_id=$TENANT_ID \
     use_microsoft_graph_api=true

This sets up Vault to be able to securely talk to the Microsoft Graph API. With these credentials Vault may then be used to assign RBAC permissions to subscriptions or it may manage service principals that are in no way related to subscriptions.

I suspect the value subscription_id is used to populate parts of API calls. If this is the case, this logic would be better implemented under the role in my opinion - this feels like the logical place to reference subscription ID.

A further future enhancement may be to support multiple configs (e.g. /azure/config/tenant_1 and /azure/config/tenant_2) as you get for instance with database secrets engines.

I hope this makes sense, if it doesn't or you require further info, please let me know and I'd be happy to discuss further.

@TimHodkin
Copy link

Hi,

I just wanted to chime in a little here.
Firstly I agree this engine is confusing when it comes to how the "vault_azure_secret_backend_role" work.

Lets confirm how I can see the functionality working and limitations.
Configuring a role using the "application_object_id" set means you can pre-create an application registration with all the permissions required, both in AAD and on Azure resources and that you can then cycle the secret for.
This is fine but requires more configuration initially to setup the service principle and means that you manage all the actual rights assignments through this SPN.

vault write azure/roles/my-role \
    application_object_id=<existing_app_obj_id> \
    ttl=1h

Configuring a role using the "azure_roles" means you can specify a role from a SUBSCRIPTION and not from AAD that you can use to generate an SPN that has access to the relevant subscription. This limitation on the roles you can specify, means you cannot use AzureAD roles to assign to the dynamic SPNs being created and HAVE to target a subscription. However you can target any subscription with a single engine, you just have to specify the full path to the role and ensure the engine has at least the role "User access Administrator" on the subscription being targeted.

vault write azure/roles/my-role ttl=1h azure_roles=-<<EOF
    [
        {
            "role_id": "/subscriptions/<Target subscription>/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7",
            "scope": "/subscriptions/<Target Subscription>
        }
    ]
EOF

So what we are left with is the "azure_groups" option when specifying a new role that you want to be dynamically created. With specifying groups you can pre-create the AzureAD groups and grant them the relevant roles that you want the SPN to have when it is created. The downside to this is you need a P2 AD licence to be able to assign roles to groups.

vault write azure/roles/my-role \
    ttl=1h \
    max_ttl=24h \
    azure_groups=<<EOF
[
  {
    "group_name": "foo"
  },
  {
    "group_name": "This won't matter as it will be overwritten",
    "object_id": "a6a834a6-36c3-4575-8e2b-05095963d603"
  }
]
EOF

limitation

What I would like to see is the ability to be able to scope the roles to AD and not just subscriptions. So being able to add an dynamic SPN to azure roles. Something like the below:

vault write azure/roles/my-role ttl=1h azure_roles=-<<EOF
    [
        {
            "role_name": "Global Reader",
            "scope": "/"
        }
    ]
EOF

Hopefully my understanding is all correct! I have only been working with vault for a short while.

I certainly dont understand the reason for the Subscription ID in the configuration and the limitation this seems to bring.

@mike-guy
Copy link

Thanks for the additional insight @TimHodkin - it seems regardless of the confusion, I need to hit the docs more and have a play! Appreciate the explanations.

@ausfestivus
Copy link

Thanks for writing this up @natilik-mikeguy. Ive raised a support case with Hashicorp to try and get this question answered. The answer will influence some decisions we are making about how we best deploy and configure this engine.

@ausfestivus
Copy link

TL;DR

If you want to use Azure Roles Names in your Vault Role definitions then operators MUST configure an Azure Secrets Enginer per Subscription.

If you would like to challenge this then please do reach out to your Hashicorp CSM or account rep and get your account tagged on FR#1204422123481069.

@F21
Copy link

F21 commented Oct 24, 2023

Agree that the current implementation is quite unwieldy. Massive +1 to @mike-guy's proposal, which makes a lot more sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants