#azure auth without using cli container?

1 messages ยท Page 1 of 1 (latest)

jagged flower
#

I have native azure SDK Go code.
I can't use it cause even when mounting $HOME/.azure, it can't resolve the credentials using default credential chain. Instead, I'd have to do a managed identity and setup more.

I want to be able to use my identity.
I can do this if I use azure cli container, but at that point I've regressing from the nice Go SDK code for processing some stuff to using azure-cli and then trying to reprocess it back into a struct. Not ideal.

Mounting $HOME/.azure might work, if I was running my Go code in the context of the azure-cli container or installing azure-cli in my container.

My understanding of the lifecycle isn't clear here.
If I use Go code I understand that Dagger is running through dagger engine for me, but I'm not certain I understand if I can impact this operating environment too to install azure-cli or layer azure cli + dagger's built binary for this code to run.

Any insight?

spark matrix
#

Can you not use the az account get-access-token command to create an access token and pass it as an argument ? eg.

dagger -c 'my-function cmd://"az account get-access-token"'
#

And then use that token as a bearer token for the Azure SDK.

glossy chasm
# spark matrix Can you not use the `az account get-access-token` command to create an access to...

this. You can do this and/or pass your $HOME/.azure to your function and export that to the SDK runtime container so you can access it from there.

In any case, following the above recommendation and/or contributing with a specialized azure secret provider: https://github.com/dagger/dagger/tree/main/engine/client/secretprovider

GitHub

An open-source runtime for composable workflows. Great for AI agents and CI/CD. - dagger/dagger

spark matrix
#

Secret providers.. how do they work ?

#

I didn't know.. nice.

glossy chasm
jagged flower
#

i'll look at what you posted, this might be useful. I know i use the get-access-token for entra auth for certain things and didn't think of passing that in as a token itself. I'll have to look how the default credential provider works and test it out ๐Ÿ‘

jagged flower
#

still looking. not certain this will work, cause the developer creds i expect to pass can't just be a pat, has to have the azure cli installed and uses this apparently.

see diagram
and second diagram for the general workflow

So while azure devops lets me do get-access-token, and pass in as a pat, the azure auth doesn't expect just a single pat.
From what I understand it also isn't compatible for windows, mac/linux in the same way, as the OS matters, and probably wouldn't let a windows user mount $HOME/.azure and get away with it.

I'm going to look again tomorrow done for the day, but hoping to avoid azure cli specific calls and use sdk, but thinking I might not be able to with dagger.
I'll have to check the bearer token approach and see if it works as didn't see anything on that yet.

This article describes how to authenticate your application to Azure services when using the Azure SDK for Go during local development using developer accounts.

This article provides an overview of how to authenticate applications to Azure services when you use the Azure SDK for Go in both server environments and in local development.

jagged flower
#

@glossy chasm is there a way for me to have a base image i create with the proper tooling and then have this as the context in which the Go SDK runs without using embedded shell commands?
in searching context7/site, gpt came up with me having to publish my function as a binary and run in go container, but this defeats the benefits I get from using Go SDK natively in my module.

Essentially is there anyway to do something like

img := client.Container().From("registry/my-base:latest").
      WithDirectory("/app", client.Host().Directory("./out")).
      WithEnvVariable("AZURE_TENANT_ID", os.Getenv("AZURE_TENANT_ID")).
      WithEntrypoint([]string{"/app/app"})

MyDaggerModule.RunAuthenticatedCommand(ctx, img)

Essentially, I see a pattern

  • of "WithExec" to just be ways to run docker commands
  • or invoke dagger module functions and they could just be native Go SDK code
  • missing: can i combine a container with certain steps to setup and still use my Go code without any shell and have it execute in this context, so any tools it would exact would be there?
jagged flower
#

I guess from what I gather in reading so far I'm actually running the Go SDK code in the dagger engine, which means I'm dealing with the base dagger engine doesn't have a tool like azure cli and i need this for proper auth resolution if I'm not using a service account. https://github.com/dagger/dagger/issues/4105

Maybe not the main solution, but might be explaining better where I"m running into an issue. The environment that my code is executing in can't resolve auth without azure cli installed, so therefore I have to resort to running docker withexec type commands instead of using Go directly.

GitHub

We have many requests from users to support a few interrelated features: Support for custom CA certs needed to connect to private registry: #3943 #2142 (comment) Setting up a custom runner not in d...

jagged flower
#

stuck on this right now and before I shelve it and move on, any quick confirmation would be great <@&946480760016207902>

tl;dr

  • i need azure-cli installed to let my mounted DefaultCredentials work for my Go code.
  • only way this works right now is running azure-cli container directly but I had azure SDK for Go natively using and performing what i needed, but I can't get it to auth as "Azure CLI not found on path" (this is a requirement for local work without a service principal setup)

So am I missing something? Is there a way to invoke my dagger Go code directly within an environment which I could have azure-cli setup (the engine?) or is this out of scope for what dagger handles right now. (that is: approach 1 wrap up other container calls/build container and use exec VS use Go code without any control of the environment it's running in)

#
Attempted credentials:
        EnvironmentCredential: missing environment variable AZURE_TENANT_ID
        WorkloadIdentityCredential: no client ID specified. Check pod configuration or set ClientID in the options
        ManagedIdentityCredential: Get "http://169.254.169.254/metadata/identity/oauth2/token": dial tcp 169.254.169.254:80: connect: connection refused
        AzureCLICredential: Azure CLI not found on path ๐Ÿ‘ˆ๐Ÿ‘ˆ๐Ÿ‘ˆ๐Ÿ‘ˆ๐Ÿ‘ˆ๐Ÿ‘ˆ  // even when including --az-creds file:///$HOME/.azure this still has requirement for azure cli
        AzureDeveloperCLICredential: Azure Developer CLI not found on path
jaunty rune
jagged flower
#

I've only gotten it to work wiith wrapping up azure-cli calls, but I had Go code I preferred to use instead of chaining cli calls.
If you figured it out with local dev credentials that would be great to know!

jaunty rune
#

Now the hard part is to find it back, pretty sure I explored that with azure or aws ahah. PS: didn't forget the Azure edge case

jagged flower
#

with aws last i used you could pass tokens and get this. With azure I don't think there's any equivalent to a "PAT". you use your identity and the azure-cli is used under the hood by all the SDK's to retrieve credential with no caching. AWS was easier for this

#

If I had a way to build a container and then invoke my dagger function in the context of that container I think it would work, but I'm not clear if there is any capability of setting that up, or if it's SDK or wrapping exec calls to another container but no hybrid style approach

spark matrix
#

Using the az account get-access-token command does not return a PAT. It returns a Bearer token, the same token the az cli uses when making API calls. I have not tested the Go Azure SDK my self, so I cannot say for sure, but I do find it unlikly that the SDK does not have a way of authenticating API calls using a supplied Bearer token some how.

jaunty rune
# jagged flower with aws last i used you could pass tokens and get this. With azure I don't thin...

Hi @jagged flower ,

Sorry about the delay, I took some extra time to dive deeper into your problem and try out a few different things.

Based on what you're trying to do, there are basically three solutions, including the Service Principal approach with environment variables, which I know you've already decided not to use.

Since we can't modify the Go SDK's base image in Dagger to include the Azure CLI, here are two alternatives I explored:

1) Using SDK User Credentials Without CLI

This approach relies solely on DeviceCodeCredential, prompting you once with a login token. After that, everything runs authenticated as your user.

Here's a quick standalone example (I made two variants, one for personal accounts and one for organizational accounts):

mkdir azure-repro-device && cd azure-repro-device
dagger init --sdk=go --name=azure-repro

Replace the generated main.go with one of these examples: https://gist.github.com/grouville/0c70568d10f2bf69cb9ec3eb688d14b8.

Then, run it like this, and it'll show you the login prompt with a device code:

dagger call list-rgs-device \
--subscription-id "$AZ_SUBSCRIPTION" \
--tenant-id "${AZ_TENANT:-}"

You'll get something like this:

Device login required.
Open https://microsoft.com/devicelogin and enter code: DXY79UCBY

This option definitely works, but my favorite solution is the next one!

#

--
2) Use the secret's ability to run arbitray commands locally

As @spark matrix pointed out, this retrieves a bearer token you can use directly. It's pretty clean and automated.

Here's the full example:

mkdir azure-repro-bearer && cd azure-repro-bearer
dagger init --sdk=go --name=azure-repro

Again, replace main.go with this example: https://gist.github.com/grouville/8b06a50613d00d77294749920480063f.

Then just run:

az login

# ARM scope for Resource Manager
SCOPE="https://management.azure.com/.default"

dagger call list-rgs-bearer \
--subscription-id "$AZ_SUBSCRIPTION" \
--arm-token=cmd://"az account get-access-token --scope $SCOPE --query accessToken -o tsv" \
--arm-expires-on=cmd://"az account get-access-token --scope $SCOPE --query expires_on -o tsv"

This works really smoothly without manual intervention:

dagger call list-rgs-bearer \                              
  --subscription-id "$AZ_SUBSCRIPTION" \
  --arm-token=cmd://"az account get-access-token --scope $SCOPE --query accessToken -o tsv" \
  --arm-expires-on=cmd://"az account get-access-token --scope $SCOPE --query expires_on -o tsv"
โ–ถ connect 0.7s
โ–ถ load module: . 0.7s
โ— parsing command line arguments 0.0s

โ— azureRepro: AzureRepro! 0.0s
โ–ถ .listRgsBearer(
  โ”† subscriptionId: "XXXXXX"
  โ”† armToken: secret(
  โ”† โ”† uri: "cmd://az account get-access-token --scope https://management.azure.com/.default --query accessToken -o tsv"
  โ”† ): Secret!
  โ”† armExpiresOn: secret(
  โ”† โ”† uri: "cmd://az account get-access-token --scope https://management.azure.com/.default --query expires_on -o tsv"
  โ”† ): Secret!
  ): String! 1.6s

[
  {
    "name": "Default...
  }
]

Hope this helps, let me know what you think!

jagged flower
#

๐Ÿ™ thank you! Exploring this now. Much appreciate being unblocked

jaunty rune
#

Keep us updated ๐Ÿ˜‡ By the way, I haven't forgotten the azure private module issue. It's just that I haven't finished setting up the infra on my side to repro

jagged flower
#

sorry posted response separately didn't see this here.
If it helps you test, I volunteer to be a test case, I can do a vscode live share/screenshare combo and we can run on my laptop as needed so you don't have to do any complex entra / auth setup. Totally willing, just hit me up with a mention and we can do anytime. I'm free all day today and also have a google calendar meeting schedule I can send you for 90 min timeblocks if you like. No pressure, but if it would help you totally willing to tag along/pair and learn/help where I can.

#

i was researching the token info in parallel, and also found similar that TokenCredential could be used without the autorotation/etc so you jump started me with this on an actual legit setup so i can test this better. Much appreciated. Might end up using service principal but in meantime this should get me going. ๐ŸŽ‰

slim roost
#

azure auth without using cli container?