go-acme / lego

Let's Encrypt/ACME client and library written in Go
https://go-acme.github.io/lego/
MIT License
7.99k stars 1.02k forks source link

Add impersonate authentification for Google Cloud #1809

Open florentinchaussoy opened 1 year ago

florentinchaussoy commented 1 year ago

Welcome

How do you use lego?

Library

Detailed Description

Hello,

I would suggest an improvement in order to cover a wider support of the Google Cloud users. Regarding authentification mechanism especially, I didn't find any way using impersonation. What do you think to include it?

Best regards.

Quick example:

--- i/providers/dns/gcloud/googlecloud.go
+++ w/providers/dns/gcloud/googlecloud.go
@@ -19,6 +19,7 @@ import (
        "golang.org/x/oauth2/google"
        "google.golang.org/api/dns/v1"
        "google.golang.org/api/googleapi"
+       "google.golang.org/api/impersonate"
        "google.golang.org/api/option"
 )

@@ -30,10 +31,11 @@ const (
 const (
        envNamespace = "GCE_"

-       EnvServiceAccount   = envNamespace + "SERVICE_ACCOUNT"
-       EnvProject          = envNamespace + "PROJECT"
-       EnvAllowPrivateZone = envNamespace + "ALLOW_PRIVATE_ZONE"
-       EnvDebug            = envNamespace + "DEBUG"
+       EnvServiceAccount            = envNamespace + "SERVICE_ACCOUNT"
+       EnvImpersonateServiceAccount = envNamespace + "IMPERSONATE_SERVICE_ACCOUNT"
+       EnvProject                   = envNamespace + "PROJECT"
+       EnvAllowPrivateZone          = envNamespace + "ALLOW_PRIVATE_ZONE"
+       EnvDebug                     = envNamespace + "DEBUG"

        EnvTTL                = envNamespace + "TTL"
        EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
@@ -162,7 +164,20 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
                return nil, errors.New("googlecloud: unable to create Google Cloud DNS service: client is nil")
        }

-       svc, err := dns.NewService(context.Background(), option.WithHTTPClient(config.HTTPClient))
+       if impersonateServiceAccount := env.GetOrFile(EnvImpersonateServiceAccount); len(impersonateServiceAccount) > 0 {
+               // Base credentials sourced from ADC or provided client options.
+               ts, err := impersonate.CredentialsTokenSource(context.Background(), impersonate.CredentialsConfig{
+                       TargetPrincipal: impersonateServiceAccount,
+                       Scopes:          []string{"https://www.googleapis.com/auth/cloud-platform"},
+               })
+               if err != nil {
+                       log.Fatal(err)
+               }
+               svc, err := dns.NewService(context.Background(), option.WithTokenSource(ts))
+       } else {
+               svc, err := dns.NewService(context.Background(), option.WithHTTPClient(config.HTTPClient))
+       }
+
        if err != nil {
                return nil, fmt.Errorf("googlecloud: unable to create Google Cloud DNS service: %w", err)
        }
ldez commented 1 year ago

Hello,

You don't provide any information about the use cases related to your suggestion, so it's not possible to have an opinion.

florentinchaussoy commented 1 year ago

According to the official documentation you can authenticate to Google APIs and services in the following ways:

I would be able to use the third method "a service account to impersonate another service account", the most secure method and not the latest - the least secure of all.

ldez commented 1 year ago

you can open a PR but you will have to improve your code (I will help you inside the PR).

florentinchaussoy commented 1 year ago

Thank you! Should I've the right to create a PR?

ldez commented 1 year ago

Should I've the right to create a PR?

There is no right to be able to open a PR.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request

florentinchaussoy commented 1 year ago
➜  lego git:(add-impersonate-support-for-gcloud)     git push --set-upstream origin add-impersonate-support-for-gcloud
remote: Permission to go-acme/lego.git denied to florentinchaussoy.
fatal: unable to access 'https://github.com/go-acme/lego.git/': The requested URL returned error: 403
ldez commented 1 year ago

I think you have to learn how to contribute to an open-source project (with forks).

florentinchaussoy commented 1 year ago

Thank you! PR has been created: https://github.com/go-acme/lego/pull/1810.

ldez commented 1 year ago

you have to improve your open source skills: