Repository: mondoohq/cnquery
Pull request #5439: ✨ Add WIF auth support
Author: login: claytoncasey01
Created: 2025-04-08T19:22:14Z | Merged: 2025-04-22T03:00:57Z

This PR includes several changes to enhance the authentication process. The most important changes are for adding support for Workload Identity Federation (WIF). 

- Integrate WIF json config into the existing `config.go` flow.
- New fields in `upstream.proto` to support `ExchangeExternalToken` endpoint
- Added an implementation of `ExchangeExternalToken` in `sts.go`, along with some helper functions to get a json token for the different providers (GCP, Azure, and Github Actions).
- Updates to `GetServiceCredential` function in `config.go` to handle a new authentication method `wif`, this uses the new `ExchangeExternalToken` and attempts to get the user a valid Service Account.

#### Testing
1. Build cnquery for linux `make cnquery/build/linux`
2. Make an auth binding for google in the UI and save it to a `.json` file
3. Upload the cnquery binary and wif config file to GCP cloud shell
4. Run `cnquery status --config path/to/config.json`


Diff:
diff --git a/cli/config/config.go b/cli/config/config.go
index 030b149a3b..a30540dba1 100644
--- a/cli/config/config.go
+++ b/cli/config/config.go
@@ -6,11 +6,13 @@ package config
 import (
 	"bytes"
 	"encoding/base64"
+	"encoding/json"
 	"os"
 	"strings"
 
 	"github.com/cockroachdb/errors"
 	"github.com/rs/zerolog/log"
+	"github.com/spf13/afero"
 	"github.com/spf13/cobra"
 	"github.com/spf13/viper"
 	"go.mondoo.com/cnquery/v11"
@@ -117,11 +119,29 @@ func InitViperConfig() {
 		_, err := AppFs.Stat(Path)
 		if err == nil {
 			log.Debug().Str("configfile", viper.ConfigFileUsed()).Msg("try to load local config file")
-			if err := viper.ReadInConfig(); err == nil {
-				LoadedConfig = true
+
+			// Check if this is a WIF config file
+			isWif := IsWifConfigFormat(Path)
+
+			if isWif {
+				log.Debug().Msg("detected WIF config file format")
+
+				// Convert the WIF config to Viper format
+				if err := ConvertWifConfig(Path, viper.GetViper()); err != nil {
+					LoadedConfig = false
+					log.Error().Err(err).Str("path", Path).Msg("could not convert WIF config file")
+				} else {
+					LoadedConfig = true
+					log.Debug().Msg("successfully converted WIF config")
+				}
 			} else {
-				LoadedConfig = false
-				log.Error().Err(err).Str("path", Path).Msg("could not read config file")
+				// Regular config file - load it normally
+				if err := viper.ReadInConfig(); err == nil {
+					LoadedConfig = true
+				} else {
+					LoadedConfig = false
+					log.Error().Err(err).Str("path", Path).Msg("could not read config file")
+				}
 			}
 		}
 	}
@@ -145,6 +165,45 @@ func InitViperConfig() {
 
 	// read in environment variables that match
 	viper.AutomaticEnv()
+
+	// Check if this is a WIF config file
+	// This detects the new format: {"type": "external_account", "audience": "...", "issuerUri": "..."}
+	if viper.GetString("type") == "external_account" {
+		log.Debug().Msg("detected WIF config format")
+
+		// Configure authentication method
+		if !viper.IsSet("auth") {
+			viper.Set("auth", map[string]string{"method": "wif"})
+		} else {
+			// If auth exists but method isn't set, set it to wif
+			authMap := viper.GetStringMap("auth")
+			if _, exists := authMap["method"]; !exists {
+				viper.Set("auth.method", "wif")
+			}
+		}
+
+		// Set the audience if available
+		if audience := viper.GetString("audience"); audience != "" {
+			viper.Set("audience", audience)
+		}
+
+		// Set the issuer URI if available
+		if issuerUri := viper.GetString("issuerUri"); issuerUri != "" {
+			viper.Set("issuer_uri", issuerUri)
+		}
+
+		// Set the API endpoint from universeDomain if available
+		if universeDomain := viper.GetString("universeDomain"); universeDomain != "" {
+			viper.Set("api_endpoint", universeDomain)
+		}
+
+		// Log the detected configuration
+		log.Debug().
+			Str("audience", viper.GetString("audience")).
+			Str("issuerUri", viper.GetString("issuer_uri")).
+			Str("apiEndpoint", viper.GetString("api_endpoint")).
+			Msg("configured WIF authentication from config file")
+	}
 }
 
 func DisplayUsedConfig() {
@@ -199,6 +258,10 @@ type CommonOpts struct {
 	// authentication
 	Authentication *CliConfigAuthentication `json:"auth,omitempty" mapstructure:"auth"`
 
+	// Workload Identity Federation fields
+	Audience  string `json:"audience,omitempty" mapstructure:"audience"`
+	IssuerURI string `json:"issuer_uri,omitempty" mapstructure:"issuer_uri"`
+
 	// client features
 	Features []string `json:"features,omitempty" mapstructure:"features"`
 
@@ -245,14 +308,28 @@ func (c *CommonOpts) GetFeatures() cnquery.Features {
 // GetServiceCredential returns the service credential that is defined in the config.
 // If no service credential is defined, it will return nil.
 func (c *CommonOpts) GetServiceCredential() *upstream.ServiceAccountCredentials {
-	if c.Authentication != nil && c.Authentication.Method == "ssh" {
-		log.Info().Msg("using ssh authentication method, generate temporary credentials")
-		serviceAccount, err := upstream.ExchangeSSHKey(c.UpstreamApiEndpoint(), c.ServiceAccountMrn, c.GetParentMrn())
-		if err != nil {
-			log.Error().Err(err).Msg("could not exchange ssh key")
-			return nil
+	// If we have an authentication method defined, use it
+	if c.Authentication != nil {
+		switch c.Authentication.Method {
+		case "ssh":
+			log.Info().Msg("using ssh authentication method, generate temporary credentials")
+			serviceAccount, err := upstream.ExchangeSSHKey(c.UpstreamApiEndpoint(), c.ServiceAccountMrn, c.GetParentMrn())
+			if err != nil {
+				log.Error().Err(err).Msg("could not exchange ssh key")
+				return nil
+			}
+			return serviceAccount
+		case "wif":
+			log.Info().Msg("using wif authentication method, generate temporary credentials")
+
+			serviceAccount, err := upstream.ExchangeExternalToken(c.UpstreamApiEndpoint(), c.Audience, c.IssuerURI)
+			if err != nil {
+				log.Error().Err(err).Msg("could not exchange external (wif) token")
+				return nil
+			}
+
+			return serviceAccount
 		}
-		return serviceAccount
 	}
 
 	// return nil when no service account is defined
@@ -304,3 +381,84 @@ func (c *CommonOpts) UpstreamApiEndpoint() string {
 
 	return apiEndpoint
 }
+
+// IsWifConfigFormat determines if a file is in the WIF config format
+func IsWifConfigFormat(filePath string) bool {
+	// Read the file
+	data, err := afero.ReadFile(AppFs, filePath)
+	if err != nil {
+		return false
+	}
+
+	// Try to parse it as JSON
+	var config map[string]interface{}
+	if err := json.Unmarshal(data, &config); err != nil {
+		return false
+	}
+
+	// Check if it has the required fields for WIF format
+	accountType, hasType := config["type"]
+	if !hasType {
+		return false
+	}
+
+	// Check if it's an external account config
+	typeStr, ok := accountType.(string)
+	if !ok || typeStr != "external_account" {
+		return false
+	}
+
+	// Check for audience
+	_, hasAudience := config["audience"]
+
+	return hasAudience
+}
+
+// ConvertWifConfig reads a WIF config file and converts it to a Viper-compatible format
+func ConvertWifConfig(filePath string, v *viper.Viper) error {
+	// Read the file
+	data, err := afero.ReadFile(AppFs, filePath)
+	if err != nil {
+		return err
+	}
+
+	// Parse it as JSON
+	var wifConfig map[string]interface{}
+	if err := json.Unmarshal(data, &wifConfig); err != nil {
+		return errors.Wrap(err, "failed to parse WIF config as JSON")
+	}
+
+	// Set the authentication method
+	v.Set("auth", map[string]string{"method": "wif"})
+
+	// Set the required fields
+	if audience, ok := wifConfig["audience"].(string); ok {
+		v.Set("audience", audience)
+	} else {
+		return errors.New("WIF config missing required 'audience' field")
+	}
+
+	// Check for universeDomain (required for API endpoint)
+	if universeDomain, ok := wifConfig["universeDomain"].(string); ok {
+		v.Set("universeDomain", universeDomain)
+		v.Set("api_endpoint", universeDomain)
+		log.Debug().Str("universeDomain", universeDomain).Msg("setting API endpoint from universeDomain")
+	} else {
+		return errors.New("WIF config missing required 'universeDomain' field")
+	}
+
+	if issuerURI, ok := wifConfig["issuerUri"].(string); ok {
+		v.Set("issuer_uri", issuerURI)
+	} else {
+		return errors.New("WIF config missing required 'issuerUri' field")
+	}
+
+	// Copy all other fields for consistency
+	for key, value := range wifConfig {
+		if key != "auth" && key != "audience" && key != "issuer_uri" && key != "api_endpoint" && key != "universeDomain" {
+			v.Set(key, value)
+		}
+	}
+
+	return nil
+}
diff --git a/cli/config/config_test.go b/cli/config/config_test.go
index 65e8373507..7e45f5513c 100644
--- a/cli/config/config_test.go
+++ b/cli/config/config_test.go
@@ -189,4 +189,160 @@ space_mrn: //captain.api.mondoo.app/spaces/musing-saha-952142
 		assert.Equal(t, "//captain.api.mondoo.app/spaces/my-space-id", cfg.GetScopeMrn())
 		assert.Equal(t, "//captain.api.mondoo.app/spaces/my-space-id", cfg.GetParentMrn())
 	})
+
+	t.Run("test WIF config format", func(t *testing.T) {
+		data := `
+{
+    "universeDomain": "https://api.example.com",
+    "scopes": [
+        "//iam.api.mondoo.app/roles/agent"
+    ],
+    "type": "external_account",
+    "audience": "//captain.api.mondoo.app/spaces/test-space-id",
+    "subjectTokenType": "urn:ietf:params:oauth:token-type:jwt",
+    "issuerUri": "https://accounts.google.com"
+}
+`
+		viper.SetConfigType("json")
+		err := viper.ReadConfig(strings.NewReader(data))
+		require.NoError(t, err)
+
+		if viper.GetString("type") == "external_account" {
+			viper.Set("auth", map[string]string{"method": "wif"})
+
+			if audience := viper.GetString("audience"); audience != "" {
+				viper.Set("audience", audience)
+			}
+
+			if issuerUri := viper.GetString("issuerUri"); issuerUri != "" {
+				viper.Set("issuer_uri", issuerUri)
+			}
+
+			if universeDomain := viper.GetString("universeDomain"); universeDomain != "" {
+				viper.Set("api_endpoint", universeDomain)
+			}
+		}
+
+		cfg, err := Read()
+		require.NoError(t, err)
+
+		assert.Equal(t, "wif", cfg.Authentication.Method)
+		assert.Equal(t, "//captain.api.mondoo.app/spaces/test-space-id", cfg.Audience)
+		assert.Equal(t, "https://accounts.google.com", cfg.IssuerURI)
+		assert.Equal(t, "https://api.example.com", cfg.APIEndpoint)
+	})
+}
+
+func TestIsWifConfigFormat(t *testing.T) {
+	resetAppFsToMemFs(t)
+
+	t.Run("valid WIF config", func(t *testing.T) {
+		wifConfig := `{
+			"universeDomain": "https://api.example.com",
+			"scopes": ["//iam.api.mondoo.app/roles/agent"],
+			"type": "external_account",
+			"audience": "//captain.api.mondoo.app/spaces/test-space-id",
+			"subjectTokenType": "urn:ietf:params:oauth:token-type:jwt",
+			"issuerUri": "https://accounts.google.com"
+		}`
+		configPath := filepath.Join(homeConfigDir, "wif_config.json")
+		require.NoError(t, afero.WriteFile(AppFs, configPath, []byte(wifConfig), 0o644))
+
+		isWif := IsWifConfigFormat(configPath)
+		assert.True(t, isWif)
+	})
+
+	t.Run("invalid JSON file", func(t *testing.T) {
+		invalidJSON := `{ "this is not valid JSON`
+		configPath := filepath.Join(homeConfigDir, "invalid.json")
+		require.NoError(t, afero.WriteFile(AppFs, configPath, []byte(invalidJSON), 0o644))
+
+		isWif := IsWifConfigFormat(configPath)
+		assert.False(t, isWif)
+	})
+
+	t.Run("non-WIF JSON config", func(t *testing.T) {
+		nonWifConfig := `{
+			"api_endpoint": "https://us.api.mondoo.com",
+			"mrn": "//agents.api.mondoo.app/spaces/my-space-id/serviceaccounts/abc123",
+			"private_key": "-----BEGIN PRIVATE KEY-----\\nkey content\\n-----END PRIVATE KEY-----\\n"
+		}`
+		configPath := filepath.Join(homeConfigDir, "non_wif.json")
+		require.NoError(t, afero.WriteFile(AppFs, configPath, []byte(nonWifConfig), 0o644))
+
+		isWif := IsWifConfigFormat(configPath)
+		assert.False(t, isWif)
+	})
+
+	t.Run("WIF config missing required fields", func(t *testing.T) {
+		missingFields := `{
+			"type": "external_account",
+			"subjectTokenType": "urn:ietf:params:oauth:token-type:jwt"
+		}`
+		configPath := filepath.Join(homeConfigDir, "missing_fields.json")
+		require.NoError(t, afero.WriteFile(AppFs, configPath, []byte(missingFields), 0o644))
+
+		isWif := IsWifConfigFormat(configPath)
+		assert.False(t, isWif)
+	})
+}
+
+func TestConvertWifConfig(t *testing.T) {
+	resetAppFsToMemFs(t)
+
+	t.Run("successful conversion", func(t *testing.T) {
+		wifConfig := `{
+			"universeDomain": "https://api.example.com",
+			"scopes": ["//iam.api.mondoo.app/roles/agent"],
+			"type": "external_account",
+			"audience": "//captain.api.mondoo.app/spaces/test-space-id",
+			"subjectTokenType": "urn:ietf:params:oauth:token-type:jwt",
+			"issuerUri": "https://accounts.google.com"
+		}`
+		configPath := filepath.Join(homeConfigDir, "wif_config.json")
+		require.NoError(t, afero.WriteFile(AppFs, configPath, []byte(wifConfig), 0o644))
+
+		v := viper.New()
+		err := ConvertWifConfig(configPath, v)
+		require.NoError(t, err)
+
+		assert.Equal(t, "wif", v.GetStringMapString("auth")["method"])
+		assert.Equal(t, "//captain.api.mondoo.app/spaces/test-space-id", v.GetString("audience"))
+		assert.Equal(t, "https://accounts.google.com", v.GetString("issuer_uri"))
+		assert.Equal(t, "https://api.example.com", v.GetString("api_endpoint"))
+		assert.Equal(t, "https://api.example.com", v.GetString("universeDomain"))
+		assert.Equal(t, "external_account", v.GetString("type"))
+	})
+
+	t.Run("missing universeDomain", func(t *testing.T) {
+		missingDomain := `{
+			"type": "external_account",
+			"audience": "//captain.api.mondoo.app/spaces/test-space-id",
+			"subjectTokenType": "urn:ietf:params:oauth:token-type:jwt",
+			"issuerUri": "https://accounts.google.com"
+		}`
+		configPath := filepath.Join(homeConfigDir, "missing_domain.json")
+		require.NoError(t, afero.WriteFile(AppFs, configPath, []byte(missingDomain), 0o644))
+
+		v := viper.New()
+		err := ConvertWifConfig(configPath, v)
+		assert.Error(t, err)
+		assert.Contains(t, err.Error(), "missing required 'universeDomain' field")
+	})
+
+	t.Run("missing audience", func(t *testing.T) {
+		missingAudience := `{
+			"universeDomain": "https://api.example.com",
+			"type": "external_account",
+			"subjectTokenType": "urn:ietf:params:oauth:token-type:jwt",
+			"issuerUri": "https://accounts.google.com"
+		}`
+		configPath := filepath.Join(homeConfigDir, "missing_audience.json")
+		require.NoError(t, afero.WriteFile(AppFs, configPath, []byte(missingAudience), 0o644))
+
+		v := viper.New()
+		err := ConvertWifConfig(configPath, v)
+		assert.Error(t, err)
+		assert.Contains(t, err.Error(), "missing required 'audience' field")
+	})
 }
diff --git a/providers-sdk/v1/upstream/mvd/cvss/cvss.pb.go b/providers-sdk/v1/upstream/mvd/cvss/cvss.pb.go
index d762885ec5..ffe3bdb630 100644
--- a/providers-sdk/v1/upstream/mvd/cvss/cvss.pb.go
+++ b/providers-sdk/v1/upstream/mvd/cvss/cvss.pb.go
@@ -3,7 +3,7 @@
 
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.36.5
+// 	protoc-gen-go v1.36.6
 // 	protoc        v5.29.3
 // source: cvss.proto
 
@@ -86,20 +86,14 @@ func (x *Cvss) GetScore() float32 {
 
 var File_cvss_proto protoreflect.FileDescriptor
 
-var file_cvss_proto_rawDesc = string([]byte{
-	0x0a, 0x0a, 0x63, 0x76, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x6d, 0x6f,
-	0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x63, 0x76, 0x73, 0x73, 0x2e, 0x76, 0x31,
-	0x22, 0x4c, 0x0a, 0x04, 0x43, 0x76, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x63, 0x74,
-	0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72,
-	0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72,
-	0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x42, 0x3e,
-	0x5a, 0x3c, 0x67, 0x6f, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
-	0x63, 0x6e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x76, 0x31, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76,
-	0x69, 0x64, 0x65, 0x72, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x70, 0x73,
-	0x74, 0x72, 0x65, 0x61, 0x6d, 0x2f, 0x6d, 0x76, 0x64, 0x2f, 0x63, 0x76, 0x73, 0x73, 0x62, 0x06,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
-})
+const file_cvss_proto_rawDesc = "" +
+	"\n" +
+	"\n" +
+	"cvss.proto\x12\x12mondoo.mvd.cvss.v1\"L\n" +
+	"\x04Cvss\x12\x16\n" +
+	"\x06vector\x18\x01 \x01(\tR\x06vector\x12\x16\n" +
+	"\x06source\x18\x02 \x01(\tR\x06source\x12\x14\n" +
+	"\x05score\x18\x03 \x01(\x02R\x05scoreB>Z<go.mondoo.com/cnquery/v11/providers-sdk/v1/upstream/mvd/cvssb\x06proto3"
 
 var (
 	file_cvss_proto_rawDescOnce sync.Once
diff --git a/providers-sdk/v1/upstream/mvd/mvd.pb.go b/providers-sdk/v1/upstream/mvd/mvd.pb.go
index e0a1f10f31..8af23b4116 100644
--- a/providers-sdk/v1/upstream/mvd/mvd.pb.go
+++ b/providers-sdk/v1/upstream/mvd/mvd.pb.go
@@ -3,7 +3,7 @@
 
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.36.5
+// 	protoc-gen-go v1.36.6
 // 	protoc        v5.29.3
 // source: mvd.proto
 
@@ -1713,310 +1713,175 @@ func (x *EndOfLifeRelease) GetChangeLogReference() string {
 
 var File_mvd_proto protoreflect.FileDescriptor
 
-var file_mvd_proto_rawDesc = string([]byte{
-	0x0a, 0x09, 0x6d, 0x76, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x6d, 0x6f, 0x6e,
-	0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67,
-	0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65,
-	0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2d, 0x70, 0x72, 0x6f,
-	0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x70,
-	0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2f, 0x6d, 0x76, 0x64, 0x2f, 0x63, 0x76, 0x73, 0x73, 0x2f,
-	0x63, 0x76, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf0, 0x01, 0x0a, 0x08, 0x50,
-	0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72,
-	0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65,
-	0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x63, 0x68, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74,
-	0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12,
-	0x14, 0x0a, 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
-	0x62, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x3b, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18,
-	0x16, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d,
-	0x76, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x4c,
-	0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65,
-	0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72,
-	0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
-	0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb3, 0x02,
-	0x0a, 0x07, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18,
-	0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
-	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a,
-	0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
-	0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x63, 0x68, 0x18,
-	0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x63, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x64,
-	0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a,
-	0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66,
-	0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18,
-	0x18, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x1c, 0x0a,
-	0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73,
-	0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
-	0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x05,
-	0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x66, 0x66, 0x65, 0x63,
-	0x74, 0x65, 0x64, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x66, 0x66, 0x65, 0x63,
-	0x74, 0x65, 0x64, 0x22, 0xa4, 0x01, 0x0a, 0x13, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x65, 0x41,
-	0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x08, 0x70,
-	0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
-	0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c,
-	0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
-	0x12, 0x32, 0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03,
-	0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e,
-	0x76, 0x31, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b,
-	0x61, 0x67, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x56, 0x65,
-	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6b, 0x65, 0x72,
-	0x6e, 0x65, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xfe, 0x01, 0x0a, 0x0a, 0x56,
-	0x75, 0x6c, 0x6e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x33, 0x0a, 0x08, 0x70, 0x6c, 0x61,
-	0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x6f,
-	0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74,
-	0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x32,
-	0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
-	0x32, 0x16, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x76, 0x31,
-	0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67,
-	0x65, 0x73, 0x12, 0x37, 0x0a, 0x0a, 0x61, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x69, 0x65, 0x73,
-	0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e,
-	0x6d, 0x76, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x79, 0x52,
-	0x0a, 0x61, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x05, 0x73,
-	0x74, 0x61, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x6f, 0x6e,
-	0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72,
-	0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x12, 0x1c, 0x0a,
-	0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x22, 0x88, 0x05, 0x0a, 0x08,
-	0x41, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x10, 0x0a, 0x03, 0x4d, 0x72, 0x6e, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4d, 0x72, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69,
-	0x74, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65,
-	0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18,
-	0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
-	0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x05, 0x66, 0x69, 0x78, 0x65, 0x64, 0x18, 0x05, 0x20, 0x03, 0x28,
-	0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x76,
-	0x31, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x05, 0x66, 0x69, 0x78, 0x65, 0x64,
-	0x12, 0x32, 0x0a, 0x08, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x03,
-	0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e,
-	0x76, 0x31, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x08, 0x61, 0x66, 0x66, 0x65,
-	0x63, 0x74, 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x04, 0x72, 0x65, 0x66, 0x73, 0x18, 0x07, 0x20, 0x03,
-	0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e,
-	0x76, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x04, 0x72, 0x65,
-	0x66, 0x73, 0x12, 0x26, 0x0a, 0x04, 0x63, 0x76, 0x65, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b,
-	0x32, 0x12, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x76, 0x31,
-	0x2e, 0x43, 0x56, 0x45, 0x52, 0x04, 0x63, 0x76, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x0e, 0x66, 0x69,
-	0x78, 0x65, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x18, 0x1e, 0x20, 0x03,
-	0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e,
-	0x76, 0x31, 0x2e, 0x46, 0x69, 0x78, 0x65, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
-	0x52, 0x0e, 0x66, 0x69, 0x78, 0x65, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73,
-	0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x19, 0x20, 0x01, 0x28, 0x05, 0x52,
-	0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x38, 0x0a, 0x0a, 0x77, 0x6f, 0x72, 0x73, 0x74, 0x53,
-	0x63, 0x6f, 0x72, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x6f, 0x6e,
-	0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x63, 0x76, 0x73, 0x73, 0x2e, 0x76, 0x31, 0x2e,
-	0x43, 0x76, 0x73, 0x73, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x73, 0x74, 0x53, 0x63, 0x6f, 0x72, 0x65,
-	0x12, 0x20, 0x0a, 0x0b, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18,
-	0x1a, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0b, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x73, 0x63, 0x6f,
-	0x72, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x1b, 0x20, 0x01, 0x28,
-	0x0e, 0x32, 0x1c, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x76,
-	0x31, 0x2e, 0x41, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52,
-	0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73,
-	0x68, 0x65, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69,
-	0x73, 0x68, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64,
-	0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64,
-	0x12, 0x22, 0x0a, 0x0c, 0x73, 0x75, 0x70, 0x65, 0x72, 0x73, 0x65, 0x64, 0x65, 0x6e, 0x63, 0x65,
-	0x18, 0x1c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x75, 0x70, 0x65, 0x72, 0x73, 0x65, 0x64,
-	0x65, 0x6e, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x6e, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x64,
-	0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x75, 0x6e, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x64,
-	0x4a, 0x04, 0x08, 0x15, 0x10, 0x16, 0x22, 0x5b, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65,
-	0x6e, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x02, 0x49, 0x44, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x14, 0x0a,
-	0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69,
-	0x74, 0x6c, 0x65, 0x22, 0xb3, 0x01, 0x0a, 0x0d, 0x46, 0x69, 0x78, 0x65, 0x64, 0x50, 0x6c, 0x61,
-	0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x06, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6c,
-	0x65, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x65,
-	0x61, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x04, 0x61, 0x72, 0x63, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73,
-	0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65,
-	0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x05,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x70,
-	0x61, 0x74, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
-	0x70, 0x61, 0x74, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xd5, 0x02, 0x0a, 0x0b, 0x52, 0x65,
-	0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f,
-	0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x12,
-	0x1a, 0x0a, 0x08, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x08, 0x52, 0x08, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75,
-	0x6e, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x75,
-	0x6e, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x0a, 0x61, 0x64, 0x76, 0x69, 0x73,
-	0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6d, 0x6f,
-	0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f,
-	0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x41, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x69, 0x65,
-	0x73, 0x52, 0x0a, 0x61, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x32, 0x0a,
-	0x04, 0x63, 0x76, 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x6f,
-	0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f,
-	0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x43, 0x76, 0x65, 0x73, 0x52, 0x04, 0x63, 0x76, 0x65,
-	0x73, 0x12, 0x3e, 0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x12, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64,
-	0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x50,
-	0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
-	0x73, 0x12, 0x3e, 0x0a, 0x08, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x69, 0x74, 0x73, 0x18, 0x13, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64,
-	0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x45,
-	0x78, 0x70, 0x6c, 0x6f, 0x69, 0x74, 0x73, 0x52, 0x08, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x69, 0x74,
-	0x73, 0x22, 0xb5, 0x01, 0x0a, 0x15, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74,
-	0x73, 0x41, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74,
-	0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61,
-	0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x05, 0x52, 0x08, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x12, 0x12, 0x0a,
-	0x04, 0x68, 0x69, 0x67, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x68, 0x69, 0x67,
-	0x68, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28,
-	0x05, 0x52, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x77,
-	0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6c, 0x6f, 0x77, 0x12, 0x12, 0x0a, 0x04, 0x6e,
-	0x6f, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x12,
-	0x18, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05,
-	0x52, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x22, 0xaf, 0x01, 0x0a, 0x0f, 0x52, 0x65,
-	0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x43, 0x76, 0x65, 0x73, 0x12, 0x14, 0x0a,
-	0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f,
-	0x74, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x12,
-	0x12, 0x0a, 0x04, 0x68, 0x69, 0x67, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x68,
-	0x69, 0x67, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x18, 0x04, 0x20,
-	0x01, 0x28, 0x05, 0x52, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x6c,
-	0x6f, 0x77, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6c, 0x6f, 0x77, 0x12, 0x12, 0x0a,
-	0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x6e, 0x6f, 0x6e,
-	0x65, 0x12, 0x18, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x18, 0x07, 0x20, 0x01,
-	0x28, 0x05, 0x52, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x22, 0xcf, 0x01, 0x0a, 0x13,
-	0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x50, 0x61, 0x63, 0x6b, 0x61,
-	0x67, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x66, 0x66,
-	0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x61, 0x66, 0x66,
-	0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61,
-	0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61,
-	0x6c, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x67, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52,
-	0x04, 0x68, 0x69, 0x67, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x18,
-	0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x12, 0x10, 0x0a,
-	0x03, 0x6c, 0x6f, 0x77, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6c, 0x6f, 0x77, 0x12,
-	0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x6e,
-	0x6f, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x18, 0x08,
-	0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x22, 0x2b, 0x0a,
-	0x13, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x45, 0x78, 0x70, 0x6c,
-	0x6f, 0x69, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0xe8, 0x02, 0x0a, 0x03, 0x43,
-	0x56, 0x45, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
-	0x49, 0x44, 0x12, 0x10, 0x0a, 0x03, 0x4d, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x03, 0x4d, 0x72, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x14,
-	0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x73,
-	0x63, 0x6f, 0x72, 0x65, 0x12, 0x38, 0x0a, 0x0a, 0x77, 0x6f, 0x72, 0x73, 0x74, 0x53, 0x63, 0x6f,
-	0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f,
-	0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x63, 0x76, 0x73, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x76,
-	0x73, 0x73, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x73, 0x74, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x1a,
-	0x0a, 0x08, 0x75, 0x6e, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08,
-	0x52, 0x08, 0x75, 0x6e, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x64, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74,
-	0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6d, 0x6f, 0x6e, 0x64,
-	0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x76, 0x65, 0x53, 0x74, 0x61,
-	0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x63, 0x76, 0x73,
-	0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f,
-	0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x63, 0x76, 0x73, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x76, 0x73,
-	0x73, 0x52, 0x04, 0x63, 0x76, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x77, 0x65, 0x18, 0x15,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, 0x77, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62,
-	0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75,
-	0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x6f, 0x64, 0x69, 0x66,
-	0x69, 0x65, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x6f, 0x64, 0x69, 0x66,
-	0x69, 0x65, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0xbc, 0x01, 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f,
-	0x72, 0x6d, 0x45, 0x6f, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x33, 0x0a, 0x08, 0x70, 0x6c, 0x61,
-	0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x6f,
-	0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74,
-	0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x18,
-	0x0a, 0x07, 0x44, 0x6f, 0x63, 0x73, 0x55, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x07, 0x44, 0x6f, 0x63, 0x73, 0x55, 0x72, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x64,
-	0x75, 0x63, 0x74, 0x55, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x50, 0x72,
-	0x6f, 0x64, 0x75, 0x63, 0x74, 0x55, 0x72, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, 0x6c, 0x65,
-	0x61, 0x73, 0x65, 0x44, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x52,
-	0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x44, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x6f,
-	0x6c, 0x44, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x45, 0x6f, 0x6c,
-	0x44, 0x61, 0x74, 0x65, 0x22, 0x44, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75,
-	0x63, 0x74, 0x45, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04,
-	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
-	0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x52, 0x0a, 0x15, 0x47, 0x65,
-	0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x45, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76,
-	0x64, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x64, 0x4f, 0x66, 0x4c, 0x69, 0x66, 0x65, 0x52, 0x65,
-	0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x22, 0xf1,
-	0x04, 0x0a, 0x10, 0x45, 0x6e, 0x64, 0x4f, 0x66, 0x4c, 0x69, 0x66, 0x65, 0x52, 0x65, 0x6c, 0x65,
-	0x61, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x6e,
-	0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61,
-	0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
-	0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x0f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x6e, 0x61, 0x6d,
-	0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x79, 0x63,
-	0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
-	0x65, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74,
-	0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
-	0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x48, 0x0a,
-	0x12, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x64,
-	0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
-	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
-	0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x10, 0x66, 0x69, 0x72, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x65,
-	0x61, 0x73, 0x65, 0x44, 0x61, 0x74, 0x65, 0x12, 0x46, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f,
-	0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0f,
-	0x6c, 0x61, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x44, 0x61, 0x74, 0x65, 0x12,
-	0x21, 0x0a, 0x0c, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x18,
-	0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4c, 0x69,
-	0x6e, 0x6b, 0x12, 0x4d, 0x0a, 0x15, 0x65, 0x6e, 0x64, 0x5f, 0x6f, 0x66, 0x5f, 0x61, 0x63, 0x74,
-	0x69, 0x76, 0x65, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x12, 0x65,
-	0x6e, 0x64, 0x4f, 0x66, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72,
-	0x74, 0x12, 0x3a, 0x0a, 0x0b, 0x65, 0x6e, 0x64, 0x5f, 0x6f, 0x66, 0x5f, 0x6c, 0x69, 0x66, 0x65,
-	0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
-	0x6d, 0x70, 0x52, 0x09, 0x65, 0x6e, 0x64, 0x4f, 0x66, 0x4c, 0x69, 0x66, 0x65, 0x12, 0x51, 0x0a,
-	0x17, 0x65, 0x6e, 0x64, 0x5f, 0x6f, 0x66, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64,
-	0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
-	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
-	0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x14, 0x65, 0x6e, 0x64, 0x4f,
-	0x66, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74,
-	0x12, 0x30, 0x0a, 0x14, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x72,
-	0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12,
-	0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e,
-	0x63, 0x65, 0x2a, 0x49, 0x0a, 0x0d, 0x41, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x79, 0x53, 0x74,
-	0x61, 0x74, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x44, 0x10,
-	0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0b,
-	0x0a, 0x07, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x44, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x4e,
-	0x4f, 0x54, 0x5f, 0x41, 0x46, 0x46, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x6f, 0x0a,
-	0x08, 0x43, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42,
-	0x4c, 0x49, 0x43, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44,
-	0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x53, 0x45, 0x52, 0x56, 0x45, 0x44, 0x10, 0x02,
-	0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x44, 0x5f, 0x42, 0x59, 0x10,
-	0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x50, 0x4c, 0x49, 0x54, 0x5f, 0x46, 0x52, 0x4f, 0x4d, 0x10,
-	0x05, 0x12, 0x0d, 0x0a, 0x09, 0x4d, 0x45, 0x52, 0x47, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x10, 0x06,
-	0x12, 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x07, 0x32, 0xfe,
-	0x01, 0x0a, 0x0f, 0x41, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x79, 0x53, 0x63, 0x61, 0x6e, 0x6e,
-	0x65, 0x72, 0x12, 0x4d, 0x0a, 0x0c, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x65, 0x41, 0x73, 0x73,
-	0x65, 0x74, 0x12, 0x22, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e,
-	0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e,
-	0x6d, 0x76, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x52, 0x65, 0x70, 0x6f, 0x72,
-	0x74, 0x12, 0x40, 0x0a, 0x05, 0x49, 0x73, 0x45, 0x6f, 0x6c, 0x12, 0x17, 0x2e, 0x6d, 0x6f, 0x6e,
-	0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66,
-	0x6f, 0x72, 0x6d, 0x1a, 0x1e, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64,
-	0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x6f, 0x6c, 0x49,
-	0x6e, 0x66, 0x6f, 0x12, 0x5a, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63,
-	0x74, 0x45, 0x6f, 0x6c, 0x12, 0x23, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x6d, 0x76,
-	0x64, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x45,
-	0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, 0x6f, 0x6e, 0x64,
-	0x6f, 0x6f, 0x2e, 0x6d, 0x76, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f,
-	0x64, 0x75, 0x63, 0x74, 0x45, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42,
-	0x39, 0x5a, 0x37, 0x67, 0x6f, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x63, 0x6f, 0x6d,
-	0x2f, 0x63, 0x6e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x76, 0x31, 0x31, 0x2f, 0x70, 0x72, 0x6f,
-	0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x70,
-	0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2f, 0x6d, 0x76, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x33,
-})
+const file_mvd_proto_rawDesc = "" +
+	"\n" +
+	"\tmvd.proto\x12\rmondoo.mvd.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a-providers-sdk/v1/upstream/mvd/cvss/cvss.proto\"\xf0\x01\n" +
+	"\bPlatform\x12\x12\n" +
+	"\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n" +
+	"\arelease\x18\x02 \x01(\tR\arelease\x12\x12\n" +
+	"\x04arch\x18\x03 \x01(\tR\x04arch\x12\x14\n" +
+	"\x05title\x18\x04 \x01(\tR\x05title\x12\x14\n" +
+	"\x05build\x18\x06 \x01(\tR\x05build\x12;\n" +
+	"\x06labels\x18\x16 \x03(\v2#.mondoo.mvd.v1.Platform.LabelsEntryR\x06labels\x1a9\n" +
+	"\vLabelsEntry\x12\x10\n" +
+	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
+	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xb3\x02\n" +
+	"\aPackage\x12\x0e\n" +
+	"\x02ID\x18\x06 \x01(\tR\x02ID\x12\x12\n" +
+	"\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n" +
+	"\aversion\x18\x02 \x01(\tR\aversion\x12\x12\n" +
+	"\x04arch\x18\x05 \x01(\tR\x04arch\x12 \n" +
+	"\vdescription\x18\x14 \x01(\tR\vdescription\x12\x16\n" +
+	"\x06format\x18\x17 \x01(\tR\x06format\x12\x16\n" +
+	"\x06origin\x18\x18 \x01(\tR\x06origin\x12\x1c\n" +
+	"\tavailable\x18\x16 \x01(\tR\tavailable\x12\x16\n" +
+	"\x06status\x18\x15 \x01(\tR\x06status\x12\x1c\n" +
+	"\tnamespace\x18\x19 \x01(\tR\tnamespace\x12\x14\n" +
+	"\x05score\x18\x1a \x01(\x05R\x05score\x12\x1a\n" +
+	"\baffected\x18\x1b \x01(\bR\baffected\"\xa4\x01\n" +
+	"\x13AnalyseAssetRequest\x123\n" +
+	"\bplatform\x18\x01 \x01(\v2\x17.mondoo.mvd.v1.PlatformR\bplatform\x122\n" +
+	"\bpackages\x18\x02 \x03(\v2\x16.mondoo.mvd.v1.PackageR\bpackages\x12$\n" +
+	"\rkernelVersion\x18\x03 \x01(\tR\rkernelVersion\"\xfe\x01\n" +
+	"\n" +
+	"VulnReport\x123\n" +
+	"\bplatform\x18\x01 \x01(\v2\x17.mondoo.mvd.v1.PlatformR\bplatform\x122\n" +
+	"\bpackages\x18\x02 \x03(\v2\x16.mondoo.mvd.v1.PackageR\bpackages\x127\n" +
+	"\n" +
+	"advisories\x18\x03 \x03(\v2\x17.mondoo.mvd.v1.AdvisoryR\n" +
+	"advisories\x120\n" +
+	"\x05stats\x18\x04 \x01(\v2\x1a.mondoo.mvd.v1.ReportStatsR\x05stats\x12\x1c\n" +
+	"\tpublished\x18\x05 \x01(\tR\tpublished\"\x88\x05\n" +
+	"\bAdvisory\x12\x0e\n" +
+	"\x02ID\x18\x01 \x01(\tR\x02ID\x12\x10\n" +
+	"\x03Mrn\x18\x02 \x01(\tR\x03Mrn\x12\x14\n" +
+	"\x05title\x18\x03 \x01(\tR\x05title\x12 \n" +
+	"\vdescription\x18\x04 \x01(\tR\vdescription\x12,\n" +
+	"\x05fixed\x18\x05 \x03(\v2\x16.mondoo.mvd.v1.PackageR\x05fixed\x122\n" +
+	"\baffected\x18\x06 \x03(\v2\x16.mondoo.mvd.v1.PackageR\baffected\x12,\n" +
+	"\x04refs\x18\a \x03(\v2\x18.mondoo.mvd.v1.ReferenceR\x04refs\x12&\n" +
+	"\x04cves\x18\x14 \x03(\v2\x12.mondoo.mvd.v1.CVER\x04cves\x12D\n" +
+	"\x0efixedPlatforms\x18\x1e \x03(\v2\x1c.mondoo.mvd.v1.FixedPlatformR\x0efixedPlatforms\x12\x14\n" +
+	"\x05score\x18\x19 \x01(\x05R\x05score\x128\n" +
+	"\n" +
+	"worstScore\x18\x1f \x01(\v2\x18.mondoo.mvd.cvss.v1.CvssR\n" +
+	"worstScore\x12 \n" +
+	"\vvendorscore\x18\x1a \x01(\x02R\vvendorscore\x122\n" +
+	"\x05state\x18\x1b \x01(\x0e2\x1c.mondoo.mvd.v1.AdvisoryStateR\x05state\x12\x1c\n" +
+	"\tpublished\x18\x17 \x01(\tR\tpublished\x12\x1a\n" +
+	"\bmodified\x18\x18 \x01(\tR\bmodified\x12\"\n" +
+	"\fsupersedence\x18\x1c \x03(\tR\fsupersedence\x12\x1a\n" +
+	"\bunscored\x18\x1d \x01(\bR\bunscoredJ\x04\b\x15\x10\x16\"[\n" +
+	"\tReference\x12\x0e\n" +
+	"\x02ID\x18\x01 \x01(\tR\x02ID\x12\x10\n" +
+	"\x03url\x18\x02 \x01(\tR\x03url\x12\x16\n" +
+	"\x06source\x18\x03 \x01(\tR\x06source\x12\x14\n" +
+	"\x05title\x18\x04 \x01(\tR\x05title\"\xb3\x01\n" +
+	"\rFixedPlatform\x12\x0e\n" +
+	"\x02ID\x18\x06 \x01(\tR\x02ID\x12\x12\n" +
+	"\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n" +
+	"\arelease\x18\x02 \x01(\tR\arelease\x12\x12\n" +
+	"\x04arch\x18\x03 \x01(\tR\x04arch\x12\x1c\n" +
+	"\tnamespace\x18\x04 \x01(\tR\tnamespace\x12\x14\n" +
+	"\x05build\x18\x05 \x01(\tR\x05build\x12\x1c\n" +
+	"\tpatchName\x18\a \x01(\tR\tpatchName\"\xd5\x02\n" +
+	"\vReportStats\x12\x14\n" +
+	"\x05score\x18\x01 \x01(\x05R\x05score\x12\x1a\n" +
+	"\baffected\x18\x02 \x01(\bR\baffected\x12\x1a\n" +
+	"\bunscored\x18\x03 \x01(\bR\bunscored\x12D\n" +
+	"\n" +
+	"advisories\x18\x10 \x01(\v2$.mondoo.mvd.v1.ReportStatsAdvisoriesR\n" +
+	"advisories\x122\n" +
+	"\x04cves\x18\x11 \x01(\v2\x1e.mondoo.mvd.v1.ReportStatsCvesR\x04cves\x12>\n" +
+	"\bpackages\x18\x12 \x01(\v2\".mondoo.mvd.v1.ReportStatsPackagesR\bpackages\x12>\n" +
+	"\bexploits\x18\x13 \x01(\v2\".mondoo.mvd.v1.ReportStatsExploitsR\bexploits\"\xb5\x01\n" +
+	"\x15ReportStatsAdvisories\x12\x14\n" +
+	"\x05total\x18\x01 \x01(\x05R\x05total\x12\x1a\n" +
+	"\bcritical\x18\x02 \x01(\x05R\bcritical\x12\x12\n" +
+	"\x04high\x18\x03 \x01(\x05R\x04high\x12\x16\n" +
+	"\x06medium\x18\x04 \x01(\x05R\x06medium\x12\x10\n" +
+	"\x03low\x18\x05 \x01(\x05R\x03low\x12\x12\n" +
+	"\x04none\x18\x06 \x01(\x05R\x04none\x12\x18\n" +
+	"\aunknown\x18\a \x01(\x05R\aunknown\"\xaf\x01\n" +
+	"\x0fReportStatsCves\x12\x14\n" +
+	"\x05total\x18\x01 \x01(\x05R\x05total\x12\x1a\n" +
+	"\bcritical\x18\x02 \x01(\x05R\bcritical\x12\x12\n" +
+	"\x04high\x18\x03 \x01(\x05R\x04high\x12\x16\n" +
+	"\x06medium\x18\x04 \x01(\x05R\x06medium\x12\x10\n" +
+	"\x03low\x18\x05 \x01(\x05R\x03low\x12\x12\n" +
+	"\x04none\x18\x06 \x01(\x05R\x04none\x12\x18\n" +
+	"\aunknown\x18\a \x01(\x05R\aunknown\"\xcf\x01\n" +
+	"\x13ReportStatsPackages\x12\x14\n" +
+	"\x05total\x18\x01 \x01(\x05R\x05total\x12\x1a\n" +
+	"\baffected\x18\x02 \x01(\x05R\baffected\x12\x1a\n" +
+	"\bcritical\x18\x03 \x01(\x05R\bcritical\x12\x12\n" +
+	"\x04high\x18\x04 \x01(\x05R\x04high\x12\x16\n" +
+	"\x06medium\x18\x05 \x01(\x05R\x06medium\x12\x10\n" +
+	"\x03low\x18\x06 \x01(\x05R\x03low\x12\x12\n" +
+	"\x04none\x18\a \x01(\x05R\x04none\x12\x18\n" +
+	"\aunknown\x18\b \x01(\x05R\aunknown\"+\n" +
+	"\x13ReportStatsExploits\x12\x14\n" +
+	"\x05total\x18\x01 \x01(\x05R\x05total\"\xe8\x02\n" +
+	"\x03CVE\x12\x0e\n" +
+	"\x02ID\x18\x01 \x01(\tR\x02ID\x12\x10\n" +
+	"\x03Mrn\x18\x02 \x01(\tR\x03Mrn\x12\x18\n" +
+	"\asummary\x18\x03 \x01(\tR\asummary\x12\x14\n" +
+	"\x05score\x18\x04 \x01(\x02R\x05score\x128\n" +
+	"\n" +
+	"worstScore\x18\a \x01(\v2\x18.mondoo.mvd.cvss.v1.CvssR\n" +
+	"worstScore\x12\x1a\n" +
+	"\bunscored\x18\x06 \x01(\bR\bunscored\x12-\n" +
+	"\x05state\x18\x05 \x01(\x0e2\x17.mondoo.mvd.v1.CveStateR\x05state\x12,\n" +
+	"\x04cvss\x18\x14 \x03(\v2\x18.mondoo.mvd.cvss.v1.CvssR\x04cvss\x12\x10\n" +
+	"\x03cwe\x18\x15 \x01(\tR\x03cwe\x12\x1c\n" +
+	"\tpublished\x18\x16 \x01(\tR\tpublished\x12\x1a\n" +
+	"\bmodified\x18\x17 \x01(\tR\bmodified\x12\x10\n" +
+	"\x03url\x18\x18 \x01(\tR\x03url\"\xbc\x01\n" +
+	"\x0fPlatformEolInfo\x123\n" +
+	"\bplatform\x18\x01 \x01(\v2\x17.mondoo.mvd.v1.PlatformR\bplatform\x12\x18\n" +
+	"\aDocsUrl\x18\x02 \x01(\tR\aDocsUrl\x12\x1e\n" +
+	"\n" +
+	"ProductUrl\x18\x03 \x01(\tR\n" +
+	"ProductUrl\x12 \n" +
+	"\vReleaseDate\x18\x04 \x01(\tR\vReleaseDate\x12\x18\n" +
+	"\aEolDate\x18\x05 \x01(\tR\aEolDate\"D\n" +
+	"\x14GetProductEolRequest\x12\x12\n" +
+	"\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n" +
+	"\aversion\x18\x02 \x01(\tR\aversion\"R\n" +
+	"\x15GetProductEolResponse\x129\n" +
+	"\arelease\x18\x01 \x01(\v2\x1f.mondoo.mvd.v1.EndOfLifeReleaseR\arelease\"\xf1\x04\n" +
+	"\x10EndOfLifeRelease\x12!\n" +
+	"\frelease_name\x18\x01 \x01(\tR\vreleaseName\x12)\n" +
+	"\x10release_codename\x18\x02 \x01(\tR\x0freleaseCodename\x12#\n" +
+	"\rrelease_cycle\x18\x03 \x01(\tR\freleaseCycle\x12%\n" +
+	"\x0elatest_version\x18\x04 \x01(\tR\rlatestVersion\x12H\n" +
+	"\x12first_release_date\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\x10firstReleaseDate\x12F\n" +
+	"\x11last_release_date\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\x0flastReleaseDate\x12!\n" +
+	"\frelease_link\x18\a \x01(\tR\vreleaseLink\x12M\n" +
+	"\x15end_of_active_support\x18\b \x01(\v2\x1a.google.protobuf.TimestampR\x12endOfActiveSupport\x12:\n" +
+	"\vend_of_life\x18\t \x01(\v2\x1a.google.protobuf.TimestampR\tendOfLife\x12Q\n" +
+	"\x17end_of_extended_support\x18\n" +
+	" \x01(\v2\x1a.google.protobuf.TimestampR\x14endOfExtendedSupport\x120\n" +
+	"\x14change_log_reference\x18\v \x01(\tR\x12changeLogReference*I\n" +
+	"\rAdvisoryState\x12\f\n" +
+	"\bRELEASED\x10\x00\x12\v\n" +
+	"\aPENDING\x10\x01\x12\v\n" +
+	"\aIGNORED\x10\x02\x12\x10\n" +
+	"\fNOT_AFFECTED\x10\x03*o\n" +
+	"\bCveState\x12\n" +
+	"\n" +
+	"\x06PUBLIC\x10\x00\x12\v\n" +
+	"\aINVALID\x10\x01\x12\f\n" +
+	"\bRESERVED\x10\x02\x12\x0f\n" +
+	"\vREPLACED_BY\x10\x04\x12\x0e\n" +
+	"\n" +
+	"SPLIT_FROM\x10\x05\x12\r\n" +
+	"\tMERGED_TO\x10\x06\x12\f\n" +
+	"\bREJECTED\x10\a2\xfe\x01\n" +
+	"\x0fAdvisoryScanner\x12M\n" +
+	"\fAnalyseAsset\x12\".mondoo.mvd.v1.AnalyseAssetRequest\x1a\x19.mondoo.mvd.v1.VulnReport\x12@\n" +
+	"\x05IsEol\x12\x17.mondoo.mvd.v1.Platform\x1a\x1e.mondoo.mvd.v1.PlatformEolInfo\x12Z\n" +
+	"\rGetProductEol\x12#.mondoo.mvd.v1.GetProductEolRequest\x1a$.mondoo.mvd.v1.GetProductEolResponseB9Z7go.mondoo.com/cnquery/v11/providers-sdk/v1/upstream/mvdb\x06proto3"
 
 var (
 	file_mvd_proto_rawDescOnce sync.Once
diff --git a/providers-sdk/v1/upstream/sts.go b/providers-sdk/v1/upstream/sts.go
index cde068bcd0..09832ee8f1 100644
--- a/providers-sdk/v1/upstream/sts.go
+++ b/providers-sdk/v1/upstream/sts.go
@@ -7,8 +7,15 @@ import (
 	"context"
 	"crypto/rand"
 	"crypto/sha256"
+	"encoding/base64"
 	"encoding/hex"
+	"encoding/json"
+	"fmt"
+	"io"
+	"net/http"
 	"net/url"
+	"os"
+	"strings"
 	"time"
 
 	"go.mondoo.com/cnquery/v11/providers/os/connection/ssh/signers"
@@ -53,6 +60,180 @@ func ExchangeSSHKey(apiEndpoint string, identityMrn string, resourceMrn string)
 	}, nil
 }
 
+func ExchangeExternalToken(apiEndpoint string, audience string, issuerURI string) (*ServiceAccountCredentials, error) {
+	// Fetch the identity token from the cloud provider
+	jsonToken, err := fetchIdentityToken(audience)
+	if err != nil {
+		return nil, err
+	}
+
+	stsClient, err := NewSecureTokenServiceClient(apiEndpoint, ranger.DefaultHttpClient())
+	if err != nil {
+		return nil, err
+	}
+
+	request := &ExchangeExternalTokenRequest{
+		Audience:  audience,
+		IssuerUri: issuerURI,
+		JwtToken:  jsonToken,
+	}
+	resp, err := stsClient.ExchangeExternalToken(context.Background(), request)
+	if err != nil {
+		return nil, err
+	}
+
+	// Decode the base64 credential string
+	credBytes, err := base64.StdEncoding.DecodeString(resp.Base64Credential)
+	if err != nil {
+		return nil, err
+	}
+
+	// First unmarshal to a temporary structure to handle the field name mismatch
+	var tempCreds struct {
+		Mrn         string `json:"mrn"`
+		ParentMrn   string `json:"parent_mrn"`
+		SpaceMrn    string `json:"space_mrn"`
+		PrivateKey  string `json:"private_key"`
+		Certificate string `json:"certificate"`
+		ApiEndpoint string `json:"api_endpoint"`
+	}
+
+	if err := json.Unmarshal(credBytes, &tempCreds); err != nil {
+		return nil, err
+	}
+
+	// Create the ServiceAccountCredentials with the correct field mapping
+	creds := ServiceAccountCredentials{
+		Mrn:         tempCreds.Mrn,
+		ParentMrn:   tempCreds.SpaceMrn,
+		ScopeMrn:    tempCreds.SpaceMrn, // Map SpaceMrn to ScopeMrn
+		PrivateKey:  tempCreds.PrivateKey,
+		Certificate: tempCreds.Certificate,
+		ApiEndpoint: tempCreds.ApiEndpoint,
+	}
+
+	return &creds, nil
+}
+
+// fetchIdentityToken fetches an identity token from the current cloud environment
+// It supports GCP, Azure, and GitHub Actions
+func fetchIdentityToken(audience string) (string, error) {
+	// Try GCP
+	if token, err := fetchGCPIdentityToken(audience); err == nil {
+		return token, nil
+	}
+
+	// Try Azure
+	if token, err := fetchAzureIdentityToken(audience); err == nil {
+		return token, nil
+	}
+
+	// Try GitHub Actions
+	if token, err := fetchGitHubActionsIdentityToken(audience); err == nil {
+		return token, nil
+	}
+
+	return "", fmt.Errorf("failed to fetch identity token from any supported cloud provider")
+}
+
+// fetchGCPIdentityToken fetches an identity token from GCP metadata service
+func fetchGCPIdentityToken(audience string) (string, error) {
+	url := fmt.Sprintf("http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=%s", audience)
+	req, err := http.NewRequest("GET", url, nil)
+	if err != nil {
+		return "", err
+	}
+	req.Header.Add("Metadata-Flavor", "Google")
+
+	client := &http.Client{Timeout: 2 * time.Second}
+	resp, err := client.Do(req)
+	if err != nil {
+		return "", err
+	}
+	defer resp.Body.Close()
+
+	if resp.StatusCode != http.StatusOK {
+		return "", fmt.Errorf("gcp metadata service returned non-OK status: %d", resp.StatusCode)
+	}
+
+	tokenBytes, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return "", err
+	}
+	return string(tokenBytes), nil
+}
+
+// fetchAzureIdentityToken fetches an identity token from Azure IMDS
+func fetchAzureIdentityToken(audience string) (string, error) {
+	reqUrl := "http://localhost:50342/oauth2/token"
+	data := make(url.Values)
+	data.Set("resource", audience)
+
+	req, err := http.NewRequest("POST", reqUrl, strings.NewReader(data.Encode()))
+	if err != nil {
+		return "", err
+	}
+	req.Header.Add("Metadata", "true")
+	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
+
+	client := &http.Client{Timeout: 2 * time.Second}
+	resp, err := client.Do(req)
+	if err != nil {
+		return "", err
+	}
+	defer resp.Body.Close()
+
+	if resp.StatusCode != http.StatusOK {
+		return "", fmt.Errorf("azure IMDS returned non-OK status: %d", resp.StatusCode)
+	}
+
+	var result struct {
+		AccessToken string `json:"access_token"`
+	}
+	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
+		return "", err
+	}
+
+	return result.AccessToken, nil
+}
+
+// fetchGitHubActionsIdentityToken fetches an identity token from GitHub Actions
+func fetchGitHubActionsIdentityToken(audience string) (string, error) {
+	tokenRequestToken := os.Getenv("ACTIONS_ID_TOKEN_REQUEST_TOKEN")
+	tokenRequestURL := os.Getenv("ACTIONS_ID_TOKEN_REQUEST_URL")
+
+	if tokenRequestToken == "" || tokenRequestURL == "" {
+		return "", fmt.Errorf("github Actions environment variables not set")
+	}
+
+	url := fmt.Sprintf("%s&audience=%s", tokenRequestURL, audience)
+	req, err := http.NewRequest("GET", url, nil)
+	if err != nil {
+		return "", err
+	}
+	req.Header.Add("Authorization", "bearer "+tokenRequestToken)
+
+	client := &http.Client{Timeout: 2 * time.Second}
+	resp, err := client.Do(req)
+	if err != nil {
+		return "", err
+	}
+	defer resp.Body.Close()
+
+	if resp.StatusCode != http.StatusOK {
+		return "", fmt.Errorf("github Actions token service returned non-OK status: %d", resp.StatusCode)
+	}
+
+	var result struct {
+		Value string `json:"value"`
+	}
+	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
+		return "", err
+	}
+
+	return result.Value, nil
+}
+
 // signClaims implements claims signing with ssh.Signer
 //
 // To generate a new SSH key use:
diff --git a/providers-sdk/v1/upstream/upstream.pb.go b/providers-sdk/v1/upstream/upstream.pb.go
index 0dafabf108..b425fa7a22 100644
--- a/providers-sdk/v1/upstream/upstream.pb.go
+++ b/providers-sdk/v1/upstream/upstream.pb.go
@@ -3,7 +3,7 @@
 
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.36.5
+// 	protoc-gen-go v1.36.6
 // 	protoc        v5.29.3
 // source: upstream.proto
 
@@ -882,165 +882,205 @@ func (x *SshSignature) GetSig() string {
 	return ""
 }
 
+type ExchangeExternalTokenRequest struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Issuer URI of the external identity provider
+	IssuerUri string `protobuf:"bytes,1,opt,name=issuer_uri,json=issuerUri,proto3" json:"issuer_uri,omitempty"`
+	// Audience for the service account
+	Audience string `protobuf:"bytes,2,opt,name=audience,proto3" json:"audience,omitempty"`
+	// Token provided by the external identity provider to exchange
+	JwtToken      string `protobuf:"bytes,3,opt,name=jwt_token,json=jwtToken,proto3" json:"jwt_token,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *ExchangeExternalTokenRequest) Reset() {
+	*x = ExchangeExternalTokenRequest{}
+	mi := &file_upstream_proto_msgTypes[14]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *ExchangeExternalTokenRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ExchangeExternalTokenRequest) ProtoMessage() {}
+
+func (x *ExchangeExternalTokenRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_upstream_proto_msgTypes[14]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ExchangeExternalTokenRequest.ProtoReflect.Descriptor instead.
+func (*ExchangeExternalTokenRequest) Descriptor() ([]byte, []int) {
+	return file_upstream_proto_rawDescGZIP(), []int{14}
+}
+
+func (x *ExchangeExternalTokenRequest) GetIssuerUri() string {
+	if x != nil {
+		return x.IssuerUri
+	}
+	return ""
+}
+
+func (x *ExchangeExternalTokenRequest) GetAudience() string {
+	if x != nil {
+		return x.Audience
+	}
+	return ""
+}
+
+func (x *ExchangeExternalTokenRequest) GetJwtToken() string {
+	if x != nil {
+		return x.JwtToken
+	}
+	return ""
+}
+
+type ExchangeExternalTokenResponse struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Base64 encoded service account credential
+	Base64Credential string `protobuf:"bytes,1,opt,name=base64_credential,json=base64Credential,proto3" json:"base64_credential,omitempty"`
+	unknownFields    protoimpl.UnknownFields
+	sizeCache        protoimpl.SizeCache
+}
+
+func (x *ExchangeExternalTokenResponse) Reset() {
+	*x = ExchangeExternalTokenResponse{}
+	mi := &file_upstream_proto_msgTypes[15]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *ExchangeExternalTokenResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ExchangeExternalTokenResponse) ProtoMessage() {}
+
+func (x *ExchangeExternalTokenResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_upstream_proto_msgTypes[15]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ExchangeExternalTokenResponse.ProtoReflect.Descriptor instead.
+func (*ExchangeExternalTokenResponse) Descriptor() ([]byte, []int) {
+	return file_upstream_proto_rawDescGZIP(), []int{15}
+}
+
+func (x *ExchangeExternalTokenResponse) GetBase64Credential() string {
+	if x != nil {
+		return x.Base64Credential
+	}
+	return ""
+}
+
 var File_upstream_proto protoreflect.FileDescriptor
 
-var file_upstream_proto_rawDesc = string([]byte{
-	0x0a, 0x0e, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x12, 0x1a, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x63, 0x6e, 0x71, 0x75, 0x65, 0x72, 0x79,
-	0x2e, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x22, 0xf5, 0x01, 0x0a,
-	0x0e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
-	0x1b, 0x0a, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x72, 0x6e, 0x12, 0x1b, 0x0a, 0x09,
-	0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6d, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4d, 0x72, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x70, 0x69,
-	0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x0b, 0x61, 0x70, 0x69, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09,
-	0x69, 0x6e, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x74, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52,
-	0x09, 0x69, 0x6e, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x74, 0x6f, 0x12, 0x4b, 0x0a, 0x05, 0x63, 0x72,
-	0x65, 0x64, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x6d, 0x6f, 0x6e, 0x64,
-	0x6f, 0x6f, 0x2e, 0x63, 0x6e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x75, 0x70, 0x73, 0x74, 0x72,
-	0x65, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x63,
-	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73,
-	0x52, 0x05, 0x63, 0x72, 0x65, 0x64, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x69, 0x5f, 0x70,
-	0x72, 0x6f, 0x78, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x69, 0x50,
-	0x72, 0x6f, 0x78, 0x79, 0x22, 0xcf, 0x01, 0x0a, 0x19, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61,
-	0x6c, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x03, 0x6d, 0x72, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6d,
-	0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74,
-	0x4d, 0x72, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b,
-	0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74,
-	0x65, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
-	0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69,
-	0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x70, 0x69, 0x5f, 0x65, 0x6e,
-	0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x70,
-	0x69, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x63, 0x6f,
-	0x70, 0x65, 0x5f, 0x6d, 0x72, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x63,
-	0x6f, 0x70, 0x65, 0x4d, 0x72, 0x6e, 0x22, 0x06, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x22, 0x06,
-	0x0a, 0x04, 0x50, 0x6f, 0x6e, 0x67, 0x22, 0x16, 0x0a, 0x14, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43,
-	0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8a,
-	0x01, 0x0a, 0x18, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74,
-	0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65,
-	0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x44, 0x0a, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69,
-	0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6d, 0x6f, 0x6e, 0x64,
-	0x6f, 0x6f, 0x2e, 0x63, 0x6e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x75, 0x70, 0x73, 0x74, 0x72,
-	0x65, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f,
-	0x52, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xb7, 0x03, 0x0a, 0x09,
-	0x41, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x72, 0x6e,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x72, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76,
-	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65,
-	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x70,
-	0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4e, 0x61, 0x6d, 0x65,
-	0x12, 0x29, 0x0a, 0x10, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x72, 0x65, 0x6c,
-	0x65, 0x61, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x6c, 0x61, 0x74,
-	0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x70,
-	0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x18, 0x06, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x41, 0x72, 0x63, 0x68,
-	0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x69, 0x70, 0x18,
-	0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x49,
-	0x70, 0x12, 0x2b, 0x0a, 0x11, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x68, 0x6f,
-	0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x70, 0x6c,
-	0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x49,
-	0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x12, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31,
-	0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x63, 0x6e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e,
-	0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x67, 0x65, 0x6e,
-	0x74, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72,
-	0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6c, 0x61,
-	0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
-	0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x49, 0x64, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61,
-	0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
-	0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
-	0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x93, 0x01, 0x0a, 0x1d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52,
-	0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-	0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74,
-	0x5f, 0x6d, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x67, 0x65, 0x6e,
-	0x74, 0x4d, 0x72, 0x6e, 0x12, 0x55, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69,
-	0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f,
-	0x6f, 0x2e, 0x63, 0x6e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65,
-	0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63,
-	0x6f, 0x75, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52,
-	0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x17, 0x0a, 0x03, 0x4d,
-	0x72, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x03, 0x6d, 0x72, 0x6e, 0x22, 0x20, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x03, 0x6d, 0x72, 0x6e, 0x22, 0x9d, 0x01, 0x0a, 0x15, 0x45, 0x78, 0x63, 0x68, 0x61,
-	0x6e, 0x67, 0x65, 0x53, 0x53, 0x48, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x12, 0x3a, 0x0a, 0x06, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x22, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x63, 0x6e, 0x71, 0x75, 0x65, 0x72,
-	0x79, 0x2e, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c,
-	0x61, 0x69, 0x6d, 0x73, 0x52, 0x06, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x12, 0x48, 0x0a, 0x0a,
-	0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
-	0x32, 0x28, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x63, 0x6e, 0x71, 0x75, 0x65, 0x72,
-	0x79, 0x2e, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x73,
-	0x68, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e,
-	0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0xaf, 0x01, 0x0a, 0x16, 0x45, 0x78, 0x63, 0x68, 0x61,
-	0x6e, 0x67, 0x65, 0x53, 0x53, 0x48, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
-	0x6d, 0x72, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x72,
-	0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4d,
-	0x72, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65,
-	0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65,
-	0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
-	0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
-	0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x70, 0x69, 0x5f, 0x65, 0x6e, 0x64,
-	0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x70, 0x69,
-	0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0x62, 0x0a, 0x06, 0x43, 0x6c, 0x61, 0x69,
-	0x6d, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x10, 0x0a, 0x03,
-	0x65, 0x78, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x65, 0x78, 0x70, 0x12, 0x10,
-	0x0a, 0x03, 0x69, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x69, 0x61, 0x74,
-	0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x44, 0x0a, 0x0c,
-	0x53, 0x73, 0x68, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x10, 0x0a, 0x03,
-	0x61, 0x6c, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x6c, 0x67, 0x12, 0x10,
-	0x0a, 0x03, 0x6b, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x69, 0x64,
-	0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73,
-	0x69, 0x67, 0x32, 0xa7, 0x03, 0x0a, 0x0c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61,
-	0x67, 0x65, 0x72, 0x12, 0x80, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
-	0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x34, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x63,
-	0x6e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e,
-	0x76, 0x31, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x6d, 0x6f,
-	0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x63, 0x6e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x75, 0x70, 0x73,
-	0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65,
-	0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72,
-	0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5c, 0x0a, 0x0f, 0x55, 0x6e, 0x52, 0x65, 0x67, 0x69,
-	0x73, 0x74, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x2e, 0x6d, 0x6f, 0x6e, 0x64,
-	0x6f, 0x6f, 0x2e, 0x63, 0x6e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x75, 0x70, 0x73, 0x74, 0x72,
-	0x65, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x72, 0x6e, 0x1a, 0x28, 0x2e, 0x6d, 0x6f, 0x6e,
-	0x64, 0x6f, 0x6f, 0x2e, 0x63, 0x6e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x75, 0x70, 0x73, 0x74,
-	0x72, 0x65, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4e, 0x0a, 0x08, 0x50, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6e, 0x67,
-	0x12, 0x20, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x63, 0x6e, 0x71, 0x75, 0x65, 0x72,
-	0x79, 0x2e, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69,
-	0x6e, 0x67, 0x1a, 0x20, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x63, 0x6e, 0x71, 0x75,
-	0x65, 0x72, 0x79, 0x2e, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e,
-	0x50, 0x6f, 0x6e, 0x67, 0x12, 0x66, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68,
-	0x65, 0x63, 0x6b, 0x12, 0x25, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x63, 0x6e, 0x71,
-	0x75, 0x65, 0x72, 0x79, 0x2e, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x76, 0x31,
-	0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x30, 0x2e, 0x6d, 0x6f, 0x6e,
-	0x64, 0x6f, 0x6f, 0x2e, 0x63, 0x6e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x75, 0x70, 0x73, 0x74,
-	0x72, 0x65, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x65,
-	0x63, 0x6b, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8c, 0x01, 0x0a,
-	0x12, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76,
-	0x69, 0x63, 0x65, 0x12, 0x76, 0x0a, 0x0b, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53,
-	0x53, 0x48, 0x12, 0x31, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x63, 0x6e, 0x71, 0x75,
-	0x65, 0x72, 0x79, 0x2e, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e,
-	0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x53, 0x48, 0x4b, 0x65, 0x79, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x63,
-	0x6e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e,
-	0x76, 0x31, 0x2e, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x53, 0x48, 0x4b, 0x65,
-	0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x35, 0x5a, 0x33, 0x67,
-	0x6f, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, 0x6f, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6e, 0x71,
-	0x75, 0x65, 0x72, 0x79, 0x2f, 0x76, 0x31, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
-	0x72, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65,
-	0x61, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
-})
+const file_upstream_proto_rawDesc = "" +
+	"\n" +
+	"\x0eupstream.proto\x12\x1amondoo.cnquery.upstream.v1\"\xf5\x01\n" +
+	"\x0eUpstreamConfig\x12\x1b\n" +
+	"\tasset_mrn\x18\x01 \x01(\tR\bassetMrn\x12\x1b\n" +
+	"\tspace_mrn\x18\x02 \x01(\tR\bspaceMrn\x12!\n" +
+	"\fapi_endpoint\x18\x03 \x01(\tR\vapiEndpoint\x12\x1c\n" +
+	"\tincognito\x18\x04 \x01(\bR\tincognito\x12K\n" +
+	"\x05creds\x18\x05 \x01(\v25.mondoo.cnquery.upstream.v1.ServiceAccountCredentialsR\x05creds\x12\x1b\n" +
+	"\tapi_proxy\x18\x06 \x01(\tR\bapiProxy\"\xcf\x01\n" +
+	"\x19ServiceAccountCredentials\x12\x10\n" +
+	"\x03mrn\x18\x01 \x01(\tR\x03mrn\x12\x1d\n" +
+	"\n" +
+	"parent_mrn\x18\x02 \x01(\tR\tparentMrn\x12\x1f\n" +
+	"\vprivate_key\x18\x03 \x01(\tR\n" +
+	"privateKey\x12 \n" +
+	"\vcertificate\x18\x04 \x01(\tR\vcertificate\x12!\n" +
+	"\fapi_endpoint\x18\x05 \x01(\tR\vapiEndpoint\x12\x1b\n" +
+	"\tscope_mrn\x18\x06 \x01(\tR\bscopeMrn\"\x06\n" +
+	"\x04Ping\"\x06\n" +
+	"\x04Pong\"\x16\n" +
+	"\x14AgentCheckinResponse\"\x8a\x01\n" +
+	"\x18AgentRegistrationRequest\x12\x14\n" +
+	"\x05token\x18\x01 \x01(\tR\x05token\x12\x12\n" +
+	"\x04name\x18\x02 \x01(\tR\x04name\x12D\n" +
+	"\n" +
+	"agent_info\x18\x03 \x01(\v2%.mondoo.cnquery.upstream.v1.AgentInfoR\tagentInfo\"\xb7\x03\n" +
+	"\tAgentInfo\x12\x10\n" +
+	"\x03mrn\x18\x01 \x01(\tR\x03mrn\x12\x18\n" +
+	"\aversion\x18\x02 \x01(\tR\aversion\x12\x14\n" +
+	"\x05build\x18\x03 \x01(\tR\x05build\x12#\n" +
+	"\rplatform_name\x18\x04 \x01(\tR\fplatformName\x12)\n" +
+	"\x10platform_release\x18\x05 \x01(\tR\x0fplatformRelease\x12#\n" +
+	"\rplatform_arch\x18\x06 \x01(\tR\fplatformArch\x12\x1f\n" +
+	"\vplatform_ip\x18\a \x01(\tR\n" +
+	"platformIp\x12+\n" +
+	"\x11platform_hostname\x18\b \x01(\tR\x10platformHostname\x12I\n" +
+	"\x06labels\x18\x12 \x03(\v21.mondoo.cnquery.upstream.v1.AgentInfo.LabelsEntryR\x06labels\x12\x1f\n" +
+	"\vplatform_id\x18\x14 \x01(\tR\n" +
+	"platformId\x1a9\n" +
+	"\vLabelsEntry\x12\x10\n" +
+	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
+	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\x93\x01\n" +
+	"\x1dAgentRegistrationConfirmation\x12\x1b\n" +
+	"\tagent_mrn\x18\x01 \x01(\tR\bagentMrn\x12U\n" +
+	"\n" +
+	"credential\x18\x02 \x01(\v25.mondoo.cnquery.upstream.v1.ServiceAccountCredentialsR\n" +
+	"credential\"\x17\n" +
+	"\x03Mrn\x12\x10\n" +
+	"\x03mrn\x18\x01 \x01(\tR\x03mrn\" \n" +
+	"\fConfirmation\x12\x10\n" +
+	"\x03mrn\x18\x01 \x01(\tR\x03mrn\"\x9d\x01\n" +
+	"\x15ExchangeSSHKeyRequest\x12:\n" +
+	"\x06claims\x18\x01 \x01(\v2\".mondoo.cnquery.upstream.v1.ClaimsR\x06claims\x12H\n" +
+	"\n" +
+	"signatures\x18\x02 \x03(\v2(.mondoo.cnquery.upstream.v1.SshSignatureR\n" +
+	"signatures\"\xaf\x01\n" +
+	"\x16ExchangeSSHKeyResponse\x12\x10\n" +
+	"\x03mrn\x18\x01 \x01(\tR\x03mrn\x12\x1d\n" +
+	"\n" +
+	"parent_mrn\x18\x02 \x01(\tR\tparentMrn\x12\x1f\n" +
+	"\vprivate_key\x18\x03 \x01(\tR\n" +
+	"privateKey\x12 \n" +
+	"\vcertificate\x18\x04 \x01(\tR\vcertificate\x12!\n" +
+	"\fapi_endpoint\x18\x05 \x01(\tR\vapiEndpoint\"b\n" +
+	"\x06Claims\x12\x18\n" +
+	"\asubject\x18\x01 \x01(\tR\asubject\x12\x10\n" +
+	"\x03exp\x18\x02 \x01(\tR\x03exp\x12\x10\n" +
+	"\x03iat\x18\x03 \x01(\tR\x03iat\x12\x1a\n" +
+	"\bresource\x18\x04 \x01(\tR\bresource\"D\n" +
+	"\fSshSignature\x12\x10\n" +
+	"\x03alg\x18\x01 \x01(\tR\x03alg\x12\x10\n" +
+	"\x03kid\x18\x02 \x01(\tR\x03kid\x12\x10\n" +
+	"\x03sig\x18\x03 \x01(\tR\x03sig\"v\n" +
+	"\x1cExchangeExternalTokenRequest\x12\x1d\n" +
+	"\n" +
+	"issuer_uri\x18\x01 \x01(\tR\tissuerUri\x12\x1a\n" +
+	"\baudience\x18\x02 \x01(\tR\baudience\x12\x1b\n" +
+	"\tjwt_token\x18\x03 \x01(\tR\bjwtToken\"L\n" +
+	"\x1dExchangeExternalTokenResponse\x12+\n" +
+	"\x11base64_credential\x18\x01 \x01(\tR\x10base64Credential2\xa7\x03\n" +
+	"\fAgentManager\x12\x80\x01\n" +
+	"\rRegisterAgent\x124.mondoo.cnquery.upstream.v1.AgentRegistrationRequest\x1a9.mondoo.cnquery.upstream.v1.AgentRegistrationConfirmation\x12\\\n" +
+	"\x0fUnRegisterAgent\x12\x1f.mondoo.cnquery.upstream.v1.Mrn\x1a(.mondoo.cnquery.upstream.v1.Confirmation\x12N\n" +
+	"\bPingPong\x12 .mondoo.cnquery.upstream.v1.Ping\x1a .mondoo.cnquery.upstream.v1.Pong\x12f\n" +
+	"\vHealthCheck\x12%.mondoo.cnquery.upstream.v1.AgentInfo\x1a0.mondoo.cnquery.upstream.v1.AgentCheckinResponse2\x9d\x02\n" +
+	"\x12SecureTokenService\x12v\n" +
+	"\vExchangeSSH\x121.mondoo.cnquery.upstream.v1.ExchangeSSHKeyRequest\x1a2.mondoo.cnquery.upstream.v1.ExchangeSSHKeyResponse\"\x00\x12\x8e\x01\n" +
+	"\x15ExchangeExternalToken\x128.mondoo.cnquery.upstream.v1.ExchangeExternalTokenRequest\x1a9.mondoo.cnquery.upstream.v1.ExchangeExternalTokenResponse\"\x00B5Z3go.mondoo.com/cnquery/v11/providers-sdk/v1/upstreamb\x06proto3"
 
 var (
 	file_upstream_proto_rawDescOnce sync.Once
@@ -1054,7 +1094,7 @@ func file_upstream_proto_rawDescGZIP() []byte {
 	return file_upstream_proto_rawDescData
 }
 
-var file_upstream_proto_msgTypes = make([]protoimpl.MessageInfo, 15)
+var file_upstream_proto_msgTypes = make([]protoimpl.MessageInfo, 17)
 var file_upstream_proto_goTypes = []any{
 	(*UpstreamConfig)(nil),                // 0: mondoo.cnquery.upstream.v1.UpstreamConfig
 	(*ServiceAccountCredentials)(nil),     // 1: mondoo.cnquery.upstream.v1.ServiceAccountCredentials
@@ -1070,12 +1110,14 @@ var file_upstream_proto_goTypes = []any{
 	(*ExchangeSSHKeyResponse)(nil),        // 11: mondoo.cnquery.upstream.v1.ExchangeSSHKeyResponse
 	(*Claims)(nil),                        // 12: mondoo.cnquery.upstream.v1.Claims
 	(*SshSignature)(nil),                  // 13: mondoo.cnquery.upstream.v1.SshSignature
-	nil,                                   // 14: mondoo.cnquery.upstream.v1.AgentInfo.LabelsEntry
+	(*ExchangeExternalTokenRequest)(nil),  // 14: mondoo.cnquery.upstream.v1.ExchangeExternalTokenRequest
+	(*ExchangeExternalTokenResponse)(nil), // 15: mondoo.cnquery.upstream.v1.ExchangeExternalTokenResponse
+	nil,                                   // 16: mondoo.cnquery.upstream.v1.AgentInfo.LabelsEntry
 }
 var file_upstream_proto_depIdxs = []int32{
 	1,  // 0: mondoo.cnquery.upstream.v1.UpstreamConfig.creds:type_name -> mondoo.cnquery.upstream.v1.ServiceAccountCredentials
 	6,  // 1: mondoo.cnquery.upstream.v1.AgentRegistrationRequest.agent_info:type_name -> mondoo.cnquery.upstream.v1.AgentInfo
-	14, // 2: mondoo.cnquery.upstream.v1.AgentInfo.labels:type_name -> mondoo.cnquery.upstream.v1.AgentInfo.LabelsEntry
+	16, // 2: mondoo.cnquery.upstream.v1.AgentInfo.labels:type_name -> mondoo.cnquery.upstream.v1.AgentInfo.LabelsEntry
 	1,  // 3: mondoo.cnquery.upstream.v1.AgentRegistrationConfirmation.credential:type_name -> mondoo.cnquery.upstream.v1.ServiceAccountCredentials
 	12, // 4: mondoo.cnquery.upstream.v1.ExchangeSSHKeyRequest.claims:type_name -> mondoo.cnquery.upstream.v1.Claims
 	13, // 5: mondoo.cnquery.upstream.v1.ExchangeSSHKeyRequest.signatures:type_name -> mondoo.cnquery.upstream.v1.SshSignature
@@ -1084,13 +1126,15 @@ var file_upstream_proto_depIdxs = []int32{
 	2,  // 8: mondoo.cnquery.upstream.v1.AgentManager.PingPong:input_type -> mondoo.cnquery.upstream.v1.Ping
 	6,  // 9: mondoo.cnquery.upstream.v1.AgentManager.HealthCheck:input_type -> mondoo.cnquery.upstream.v1.AgentInfo
 	10, // 10: mondoo.cnquery.upstream.v1.SecureTokenService.ExchangeSSH:input_type -> mondoo.cnquery.upstream.v1.ExchangeSSHKeyRequest
-	7,  // 11: mondoo.cnquery.upstream.v1.AgentManager.RegisterAgent:output_type -> mondoo.cnquery.upstream.v1.AgentRegistrationConfirmation
-	9,  // 12: mondoo.cnquery.upstream.v1.AgentManager.UnRegisterAgent:output_type -> mondoo.cnquery.upstream.v1.Confirmation
-	3,  // 13: mondoo.cnquery.upstream.v1.AgentManager.PingPong:output_type -> mondoo.cnquery.upstream.v1.Pong
-	4,  // 14: mondoo.cnquery.upstream.v1.AgentManager.HealthCheck:output_type -> mondoo.cnquery.upstream.v1.AgentCheckinResponse
-	11, // 15: mondoo.cnquery.upstream.v1.SecureTokenService.ExchangeSSH:output_type -> mondoo.cnquery.upstream.v1.ExchangeSSHKeyResponse
-	11, // [11:16] is the sub-list for method output_type
-	6,  // [6:11] is the sub-list for method input_type
+	14, // 11: mondoo.cnquery.upstream.v1.SecureTokenService.ExchangeExternalToken:input_type -> mondoo.cnquery.upstream.v1.ExchangeExternalTokenRequest
+	7,  // 12: mondoo.cnquery.upstream.v1.AgentManager.RegisterAgent:output_type -> mondoo.cnquery.upstream.v1.AgentRegistrationConfirmation
+	9,  // 13: mondoo.cnquery.upstream.v1.AgentManager.UnRegisterAgent:output_type -> mondoo.cnquery.upstream.v1.Confirmation
+	3,  // 14: mondoo.cnquery.upstream.v1.AgentManager.PingPong:output_type -> mondoo.cnquery.upstream.v1.Pong
+	4,  // 15: mondoo.cnquery.upstream.v1.AgentManager.HealthCheck:output_type -> mondoo.cnquery.upstream.v1.AgentCheckinResponse
+	11, // 16: mondoo.cnquery.upstream.v1.SecureTokenService.ExchangeSSH:output_type -> mondoo.cnquery.upstream.v1.ExchangeSSHKeyResponse
+	15, // 17: mondoo.cnquery.upstream.v1.SecureTokenService.ExchangeExternalToken:output_type -> mondoo.cnquery.upstream.v1.ExchangeExternalTokenResponse
+	12, // [12:18] is the sub-list for method output_type
+	6,  // [6:12] is the sub-list for method input_type
 	6,  // [6:6] is the sub-list for extension type_name
 	6,  // [6:6] is the sub-list for extension extendee
 	0,  // [0:6] is the sub-list for field type_name
@@ -1107,7 +1151,7 @@ func file_upstream_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: unsafe.Slice(unsafe.StringData(file_upstream_proto_rawDesc), len(file_upstream_proto_rawDesc)),
 			NumEnums:      0,
-			NumMessages:   15,
+			NumMessages:   17,
 			NumExtensions: 0,
 			NumServices:   2,
 		},
diff --git a/providers-sdk/v1/upstream/upstream.proto b/providers-sdk/v1/upstream/upstream.proto
index 1e1ed04469..b2f96e6972 100644
--- a/providers-sdk/v1/upstream/upstream.proto
+++ b/providers-sdk/v1/upstream/upstream.proto
@@ -13,6 +13,7 @@ message UpstreamConfig {
   bool incognito = 4;
   ServiceAccountCredentials creds = 5;
   string api_proxy = 6;
+
 }
 
 // ServiceAccountCredentials are used to authenticate with Mondoo Platform
@@ -92,6 +93,8 @@ message Confirmation {
 
 service SecureTokenService {
   rpc ExchangeSSH (ExchangeSSHKeyRequest) returns (ExchangeSSHKeyResponse) {}
+  rpc ExchangeExternalToken (ExchangeExternalTokenRequest)
+      returns (ExchangeExternalTokenResponse) {}
 }
 
 message ExchangeSSHKeyRequest {
@@ -122,3 +125,17 @@ message SshSignature {
   string kid = 2;
   string sig = 3;
 }
+
+message ExchangeExternalTokenRequest {
+  // Issuer URI of the external identity provider
+  string issuer_uri = 1;
+  // Audience for the service account
+  string audience = 2;
+  // Token provided by the external identity provider to exchange
+  string jwt_token = 3;
+}
+
+message ExchangeExternalTokenResponse {
+  // Base64 encoded service account credential
+  string base64_credential = 1;
+}
diff --git a/providers-sdk/v1/upstream/upstream.ranger.go b/providers-sdk/v1/upstream/upstream.ranger.go
index 23f9f7aa35..b75afd0555 100644
--- a/providers-sdk/v1/upstream/upstream.ranger.go
+++ b/providers-sdk/v1/upstream/upstream.ranger.go
@@ -209,6 +209,7 @@ func (p *AgentManagerServer) HealthCheck(ctx context.Context, reqBytes *[]byte)
 
 type SecureTokenService interface {
 	ExchangeSSH(context.Context, *ExchangeSSHKeyRequest) (*ExchangeSSHKeyResponse, error)
+	ExchangeExternalToken(context.Context, *ExchangeExternalTokenRequest) (*ExchangeExternalTokenResponse, error)
 }
 
 // client implementation
@@ -242,6 +243,11 @@ func (c *SecureTokenServiceClient) ExchangeSSH(ctx context.Context, in *Exchange
 	err := c.DoClientRequest(ctx, c.httpclient, strings.Join([]string{c.prefix, "/ExchangeSSH"}, ""), in, out)
 	return out, err
 }
+func (c *SecureTokenServiceClient) ExchangeExternalToken(ctx context.Context, in *ExchangeExternalTokenRequest) (*ExchangeExternalTokenResponse, error) {
+	out := new(ExchangeExternalTokenResponse)
+	err := c.DoClientRequest(ctx, c.httpclient, strings.Join([]string{c.prefix, "/ExchangeExternalToken"}, ""), in, out)
+	return out, err
+}
 
 // server implementation
 
@@ -265,7 +271,8 @@ func NewSecureTokenServiceServer(handler SecureTokenService, opts ...SecureToken
 	service := ranger.Service{
 		Name: "SecureTokenService",
 		Methods: map[string]ranger.Method{
-			"ExchangeSSH": srv.ExchangeSSH,
+			"ExchangeSSH":           srv.ExchangeSSH,
+			"ExchangeExternalToken": srv.ExchangeExternalToken,
 		},
 	}
 	return ranger.NewRPCServer(&service)
@@ -300,3 +307,27 @@ func (p *SecureTokenServiceServer) ExchangeSSH(ctx context.Context, reqBytes *[]
 	}
 	return p.handler.ExchangeSSH(ctx, &req)
 }
+func (p *SecureTokenServiceServer) ExchangeExternalToken(ctx context.Context, reqBytes *[]byte) (pb.Message, error) {
+	var req ExchangeExternalTokenRequest
+	var err error
+
+	md, ok := metadata.FromIncomingContext(ctx)
+	if !ok {
+		return nil, errors.New("could not access header")
+	}
+
+	switch md.First("Content-Type") {
+	case "application/protobuf", "application/octet-stream", "application/grpc+proto":
+		err = pb.Unmarshal(*reqBytes, &req)
+	default:
+		// handle case of empty object
+		if len(*reqBytes) > 0 {
+			err = jsonpb.UnmarshalOptions{DiscardUnknown: true}.Unmarshal(*reqBytes, &req)
+		}
+	}
+
+	if err != nil {
+		return nil, err
+	}
+	return p.handler.ExchangeExternalToken(ctx, &req)
+}


Reviews:
user: login: jaym
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T17:53:57Z
user: login: jaym
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T17:56:41Z
user: login: claytoncasey01
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T19:29:21Z
user: login: claytoncasey01
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T21:37:43Z
user: login: vjeffrey
body: thank you, this is working great! 
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-21T16:59:02Z
user: login: afiune
body: <img src="https://media1.giphy.com/media/v1.Y2lkPWJkM2VhNTdlcnE0eDE5N3ZobHFmc2M0bnRrN3hiY2RyejQ4MThxdDM3dmp5c2NpbSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/AuwBPJztsEWkw/giphy.gif"/>
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-21T22:20:28Z
user: login: claytoncasey01
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-21T23:40:22Z
user: login: claytoncasey01
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-21T23:40:37Z
user: login: claytoncasey01
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-21T23:59:54Z

Review comments:
diff_hunk: @@ -117,15 +119,73 @@ func InitViperConfig() {
 		_, err := AppFs.Stat(Path)
 		if err == nil {
 			log.Debug().Str("configfile", viper.ConfigFileUsed()).Msg("try to load local config file")
-			if err := viper.ReadInConfig(); err == nil {
-				LoadedConfig = true
+
+			// Check if this is a WIF config file
+			isWif, wifErr := IsWifConfigFormat(Path)
path: cli/config/config.go
user: login: jaym
body: is it not possible to make wif config a subset of our normal config file?
created_at: 2025-04-16T17:53:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -53,6 +60,194 @@ func ExchangeSSHKey(apiEndpoint string, identityMrn string, resourceMrn string)
 	}, nil
 }
 
+func ExchangeExternalToken(apiEndpoint string, audience string, issuerURI string) (*ServiceAccountCredentials, error) {
+	// Fetch the identity token from the cloud provider
+	jsonToken, provider, err := fetchIdentityToken(audience)
+	if err != nil {
+		return nil, err
+	}
+
+	stsClient, err := NewSecureTokenServiceClient(apiEndpoint, ranger.DefaultHttpClient())
+	if err != nil {
+		return nil, err
+	}
+
+	// If issuerURI is not provided, default based on the provider
+	if issuerURI == "" {
+		switch provider {
+		case "gcp":
+			issuerURI = "https://accounts.google.com"
+		case "azure":
+			issuerURI = "https://sts.windows.net/"
+		case "github":
+			issuerURI = "https://token.actions.githubusercontent.com"
+		default:
+			issuerURI = "https://accounts.google.com"
path: providers-sdk/v1/upstream/sts.go
user: login: jaym
body: probably just want to error here?
created_at: 2025-04-16T17:56:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -117,15 +119,73 @@ func InitViperConfig() {
 		_, err := AppFs.Stat(Path)
 		if err == nil {
 			log.Debug().Str("configfile", viper.ConfigFileUsed()).Msg("try to load local config file")
-			if err := viper.ReadInConfig(); err == nil {
-				LoadedConfig = true
+
+			// Check if this is a WIF config file
+			isWif, wifErr := IsWifConfigFormat(Path)
path: cli/config/config.go
user: login: claytoncasey01
body: Maybe, I will look into that a bit. 
created_at: 2025-04-16T19:29:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -53,6 +60,194 @@ func ExchangeSSHKey(apiEndpoint string, identityMrn string, resourceMrn string)
 	}, nil
 }
 
+func ExchangeExternalToken(apiEndpoint string, audience string, issuerURI string) (*ServiceAccountCredentials, error) {
+	// Fetch the identity token from the cloud provider
+	jsonToken, provider, err := fetchIdentityToken(audience)
+	if err != nil {
+		return nil, err
+	}
+
+	stsClient, err := NewSecureTokenServiceClient(apiEndpoint, ranger.DefaultHttpClient())
+	if err != nil {
+		return nil, err
+	}
+
+	// If issuerURI is not provided, default based on the provider
+	if issuerURI == "" {
+		switch provider {
+		case "gcp":
+			issuerURI = "https://accounts.google.com"
+		case "azure":
+			issuerURI = "https://sts.windows.net/"
+		case "github":
+			issuerURI = "https://token.actions.githubusercontent.com"
+		default:
+			issuerURI = "https://accounts.google.com"
path: providers-sdk/v1/upstream/sts.go
user: login: claytoncasey01
body: Thinking about it, yeah, since we are now using the config the UI gives after creating the binding, this whole switch can go away since it should always have an issuerURI and if it doesn't then that's an error. 
created_at: 2025-04-16T21:37:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -117,15 +119,73 @@ func InitViperConfig() {
 		_, err := AppFs.Stat(Path)
 		if err == nil {
 			log.Debug().Str("configfile", viper.ConfigFileUsed()).Msg("try to load local config file")
-			if err := viper.ReadInConfig(); err == nil {
-				LoadedConfig = true
+
+			// Check if this is a WIF config file
+			isWif, wifErr := IsWifConfigFormat(Path)
path: cli/config/config.go
user: login: afiune
body: Can we get rid of the error in this function and only return a boolean? 99% of the times we won't hit it and when we do, it won't be useful to print an error that says that we couldn't read the config file since we will later try to read it.
created_at: 2025-04-21T21:54:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -117,13 +119,71 @@ func InitViperConfig() {
 		_, err := AppFs.Stat(Path)
 		if err == nil {
 			log.Debug().Str("configfile", viper.ConfigFileUsed()).Msg("try to load local config file")
-			if err := viper.ReadInConfig(); err == nil {
-				LoadedConfig = true
+
+			// Check if this is a WIF config file
+			isWif, wifErr := IsWifConfigFormat(Path)
+			if wifErr != nil {
+				log.Debug().Err(wifErr).Msg("error checking for WIF config format")
+			} else if isWif {
+				log.Debug().Msg("detected WIF config file format")
+
+				// Convert the WIF config to Viper format
+				if err := ConvertWifConfig(Path, viper.GetViper()); err != nil {
+					LoadedConfig = false
+					log.Error().Err(err).Str("path", Path).Msg("could not convert WIF config file")
+				} else {
+					LoadedConfig = true
+					log.Debug().Msg("successfully converted WIF config")
+				}
 			} else {
-				LoadedConfig = false
-				log.Error().Err(err).Str("path", Path).Msg("could not read config file")
+				// Regular config file - load it normally
+				if err := viper.ReadInConfig(); err == nil {
+					LoadedConfig = true
+				} else {
+					LoadedConfig = false
+					log.Error().Err(err).Str("path", Path).Msg("could not read config file")
+				}
+			}
+		}
+	}
+
+	// Check if this is a WIF config file
+	// This detects the new format: {"type": "external_account", "audience": "...", "issuerUri": "..."}
+	if viper.GetString("type") == "external_account" {
+		log.Debug().Msg("detected WIF config format")
+
+		// Configure authentication method
+		if !viper.IsSet("auth") {
+			viper.Set("auth", map[string]string{"method": "wif"})
+		} else {
+			// If auth exists but method isn't set, set it to wif
+			authMap := viper.GetStringMap("auth")
+			if _, exists := authMap["method"]; !exists {
+				viper.Set("auth.method", "wif")
 			}
 		}
+
+		// Set the audience if available
+		if audience := viper.GetString("audience"); audience != "" {
+			viper.Set("audience", audience)
+		}
+
+		// Set the issuer URI if available
+		if issuerUri := viper.GetString("issuerUri"); issuerUri != "" {
+			viper.Set("issuer_uri", issuerUri)
+		}
+
+		// Set the API endpoint from universeDomain if available
+		if universeDomain := viper.GetString("universeDomain"); universeDomain != "" {
path: cli/config/config.go
user: login: afiune
body: Since all of these `viper.Get` function calls are happening before `viper.AutomaticEnv`, we won't have support for loading these options from environment variables.

If we want support, I would recommend moving them down below.


created_at: 2025-04-21T22:00:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -245,14 +309,56 @@ func (c *CommonOpts) GetFeatures() cnquery.Features {
 // GetServiceCredential returns the service credential that is defined in the config.
 // If no service credential is defined, it will return nil.
 func (c *CommonOpts) GetServiceCredential() *upstream.ServiceAccountCredentials {
-	if c.Authentication != nil && c.Authentication.Method == "ssh" {
-		log.Info().Msg("using ssh authentication method, generate temporary credentials")
-		serviceAccount, err := upstream.ExchangeSSHKey(c.UpstreamApiEndpoint(), c.ServiceAccountMrn, c.GetParentMrn())
-		if err != nil {
-			log.Error().Err(err).Msg("could not exchange ssh key")
-			return nil
+	// If we have an authentication method defined, use it
+	if c.Authentication != nil {
+		switch c.Authentication.Method {
+		case "ssh":
+			log.Info().Msg("using ssh authentication method, generate temporary credentials")
+			serviceAccount, err := upstream.ExchangeSSHKey(c.UpstreamApiEndpoint(), c.ServiceAccountMrn, c.GetParentMrn())
+			if err != nil {
+				log.Error().Err(err).Msg("could not exchange ssh key")
+				return nil
+			}
+			return serviceAccount
+		case "wif":
+			log.Info().Msg("using wif authentication method, generate temporary credentials")
+
+			// Validate required fields for WIF
+			if c.Audience == "" {
+				log.Error().Msg("missing required field 'audience' for WIF authentication")
+				return nil
+			}
+
+			// If apiEndpoint is not set, check for universeDomain in viper
+			if c.APIEndpoint == "" {
+				universeDomain := viper.GetString("universeDomain")
path: cli/config/config.go
user: login: afiune
body: How can we end up here? If we have `c.Authentication.Method == "wif"` I think it means we loaded the WIF config during `InitViperConfig` so this feels redundant and we should get rid of it unless we are covering some edge case that I am not seeing. 🤔 
created_at: 2025-04-21T22:10:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -295,6 +401,11 @@ func (c *CommonOpts) GetParentMrn() string {
 }
 
 func (c *CommonOpts) UpstreamApiEndpoint() string {
+	// First check for environment variable override
+	if envEndpoint := os.Getenv("MONDOO_API_ENDPOINT"); envEndpoint != "" {
path: cli/config/config.go
user: login: afiune
body: The loading of environment variables like this one happens automatically, why do we need this? 
created_at: 2025-04-21T22:12:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -245,14 +309,56 @@ func (c *CommonOpts) GetFeatures() cnquery.Features {
 // GetServiceCredential returns the service credential that is defined in the config.
 // If no service credential is defined, it will return nil.
 func (c *CommonOpts) GetServiceCredential() *upstream.ServiceAccountCredentials {
-	if c.Authentication != nil && c.Authentication.Method == "ssh" {
-		log.Info().Msg("using ssh authentication method, generate temporary credentials")
-		serviceAccount, err := upstream.ExchangeSSHKey(c.UpstreamApiEndpoint(), c.ServiceAccountMrn, c.GetParentMrn())
-		if err != nil {
-			log.Error().Err(err).Msg("could not exchange ssh key")
-			return nil
+	// If we have an authentication method defined, use it
+	if c.Authentication != nil {
+		switch c.Authentication.Method {
+		case "ssh":
+			log.Info().Msg("using ssh authentication method, generate temporary credentials")
+			serviceAccount, err := upstream.ExchangeSSHKey(c.UpstreamApiEndpoint(), c.ServiceAccountMrn, c.GetParentMrn())
+			if err != nil {
+				log.Error().Err(err).Msg("could not exchange ssh key")
+				return nil
+			}
+			return serviceAccount
+		case "wif":
+			log.Info().Msg("using wif authentication method, generate temporary credentials")
+
+			// Validate required fields for WIF
+			if c.Audience == "" {
+				log.Error().Msg("missing required field 'audience' for WIF authentication")
+				return nil
+			}
+
+			// If apiEndpoint is not set, check for universeDomain in viper
+			if c.APIEndpoint == "" {
+				universeDomain := viper.GetString("universeDomain")
path: cli/config/config.go
user: login: claytoncasey01
body: Yeah this is definitely redundant, removed.
created_at: 2025-04-21T23:40:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -295,6 +401,11 @@ func (c *CommonOpts) GetParentMrn() string {
 }
 
 func (c *CommonOpts) UpstreamApiEndpoint() string {
+	// First check for environment variable override
+	if envEndpoint := os.Getenv("MONDOO_API_ENDPOINT"); envEndpoint != "" {
path: cli/config/config.go
user: login: claytoncasey01
body: Left overs from when I was passing this stuff as flags in cnspec, removed.
created_at: 2025-04-21T23:40:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -117,13 +119,71 @@ func InitViperConfig() {
 		_, err := AppFs.Stat(Path)
 		if err == nil {
 			log.Debug().Str("configfile", viper.ConfigFileUsed()).Msg("try to load local config file")
-			if err := viper.ReadInConfig(); err == nil {
-				LoadedConfig = true
+
+			// Check if this is a WIF config file
+			isWif, wifErr := IsWifConfigFormat(Path)
+			if wifErr != nil {
+				log.Debug().Err(wifErr).Msg("error checking for WIF config format")
+			} else if isWif {
+				log.Debug().Msg("detected WIF config file format")
+
+				// Convert the WIF config to Viper format
+				if err := ConvertWifConfig(Path, viper.GetViper()); err != nil {
+					LoadedConfig = false
+					log.Error().Err(err).Str("path", Path).Msg("could not convert WIF config file")
+				} else {
+					LoadedConfig = true
+					log.Debug().Msg("successfully converted WIF config")
+				}
 			} else {
-				LoadedConfig = false
-				log.Error().Err(err).Str("path", Path).Msg("could not read config file")
+				// Regular config file - load it normally
+				if err := viper.ReadInConfig(); err == nil {
+					LoadedConfig = true
+				} else {
+					LoadedConfig = false
+					log.Error().Err(err).Str("path", Path).Msg("could not read config file")
+				}
+			}
+		}
+	}
+
+	// Check if this is a WIF config file
+	// This detects the new format: {"type": "external_account", "audience": "...", "issuerUri": "..."}
+	if viper.GetString("type") == "external_account" {
+		log.Debug().Msg("detected WIF config format")
+
+		// Configure authentication method
+		if !viper.IsSet("auth") {
+			viper.Set("auth", map[string]string{"method": "wif"})
+		} else {
+			// If auth exists but method isn't set, set it to wif
+			authMap := viper.GetStringMap("auth")
+			if _, exists := authMap["method"]; !exists {
+				viper.Set("auth.method", "wif")
 			}
 		}
+
+		// Set the audience if available
+		if audience := viper.GetString("audience"); audience != "" {
+			viper.Set("audience", audience)
+		}
+
+		// Set the issuer URI if available
+		if issuerUri := viper.GetString("issuerUri"); issuerUri != "" {
+			viper.Set("issuer_uri", issuerUri)
+		}
+
+		// Set the API endpoint from universeDomain if available
+		if universeDomain := viper.GetString("universeDomain"); universeDomain != "" {
path: cli/config/config.go
user: login: claytoncasey01
body: Nice catch! Moved the `viper.Get` calls below `viper.AutomaticEnv` with my latest push.
created_at: 2025-04-21T23:59:53Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-04-08T19:24:32Z
body: ## Test Results
4 212 tests  +10   4 208 ✅ +10   2m 3s ⏱️ -16s
  401 suites ± 0       4 💤 ± 0 
   30 files   ± 0       0 ❌ ± 0 

Results for commit e0e38d7e. ± Comparison against base commit 5542f562.

[test-results]:data:application/gzip;base64,H4sIAKTeBmgC/13MQQ7CIBRF0a00jB0AvxZwM4bCJyG2xVAYNe5ditoSh/e85G3E+QlXcuuAXjqyZp9q9ZSVtDnq5MNSgHEoUMZUZ874L+9rNqYalac9/HO3A5z2UwF6AMYY4ldiXprXvf5OP3R+1m4ua7ePJsyzTyUIUgRpBXIBBsQ4XFE6qZjlvULtlHSgxMDNSF5v277NMAwBAAA=

:recycle: This comment has been updated with latest results.
author_association: CONTRIBUTOR
user: login: vjeffrey
created_at: 2025-04-21T15:24:08Z
body: ✨ im gonna set aside some time to review this later today, thank you!
author_association: CONTRIBUTOR