{"record":{"id":"aa034b380980cf24","repo":"grpc/grpc-go","slug":"alts-untrusted-platform-alts-is-only-supported-o","errorCode":null,"errorMessage":"ALTS: untrusted platform. ALTS is only supported on GCP","messagePattern":"ALTS: untrusted platform\\. ALTS is only supported on GCP","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/alts/alts.go","lineNumber":71,"sourceCode":"\tprotocolVersionMinMajor = 2\n\tprotocolVersionMinMinor = 1\n)\n\nvar (\n\tvmOnGCP       bool\n\tonce          sync.Once\n\tmaxRPCVersion = &altspb.RpcProtocolVersions_Version{\n\t\tMajor: protocolVersionMaxMajor,\n\t\tMinor: protocolVersionMaxMinor,\n\t}\n\tminRPCVersion = &altspb.RpcProtocolVersions_Version{\n\t\tMajor: protocolVersionMinMajor,\n\t\tMinor: protocolVersionMinMinor,\n\t}\n\t// ErrUntrustedPlatform is returned from ClientHandshake and\n\t// ServerHandshake is running on a platform where the trustworthiness of\n\t// the handshaker service is not guaranteed.\n\tErrUntrustedPlatform = errors.New(\"ALTS: untrusted platform. ALTS is only supported on GCP\")\n\tlogger               = grpclog.Component(\"alts\")\n)\n\n// AuthInfo exposes security information from the ALTS handshake to the\n// application. This interface is to be implemented by ALTS. Users should not\n// need a brand new implementation of this interface. For situations like\n// testing, any new implementation should embed this interface. This allows\n// ALTS to add new methods to this interface.\ntype AuthInfo interface {\n\t// ApplicationProtocol returns application protocol negotiated for the\n\t// ALTS connection.\n\tApplicationProtocol() string\n\t// RecordProtocol returns the record protocol negotiated for the ALTS\n\t// connection.\n\tRecordProtocol() string\n\t// SecurityLevel returns the security level of the created ALTS secure\n\t// channel.\n\tSecurityLevel() altspb.SecurityLevel","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/credentials/alts/alts.go#L53-L89","documentation":"ErrUntrustedPlatform (credentials/alts/alts.go:68-71) is returned from both altsTC.ClientHandshake and ServerHandshake when vmOnGCP is false. vmOnGCP is set once via googlecloud.OnGCE() (alts.go:155) — ALTS relies on a hypervisor-provided handshaker service whose trustworthiness is only guaranteed on GCE/GKE/Cloud Run.","triggerScenarios":"Code using alts.NewClientCreds()/alts.NewServerCreds() runs the handshake (clientconn.go dial → transport → ClientHandshake at alts.go:172-175, or server side at alts.go:218-221) on a host where googlecloud.OnGCE() returned false (not a GCE metadata server).","commonSituations":"Running ALTS locally or on AWS/on-prem; CI that is not on GCP; tests that forgot to force vmOnGCP=true (see alts_test.go:58-62); a container without metadata-server access.","solutions":["Deploy the workload to GCP (GCE/GKE/Cloud Run/Cloud Functions) where the ALTS handshaker is available.","Off-GCP, switch to TLS: grpc.WithTransportCredentials(credentials.NewTLS(tlsConf)) instead of ALTS.","For local dev use insecure.NewCredentials() explicitly (never in production).","In ALTS unit tests, set the unexported vmOnGCP via an internal test build or run the test on GCP."],"exampleFix":"// before — ALTS off GCP\ncc, _ := grpc.NewClient(target,\n    grpc.WithTransportCredentials(alts.NewClientCreds(opts)))\n// handshake error: ALTS: untrusted platform. ALTS is only supported on GCP\n\n// after — TLS off GCP, ALTS only on GCP\nvar creds credentials.TransportCredentials\nif onGCP {\n    creds = alts.NewClientCreds(opts)\n} else {\n    creds = credentials.NewTLS(tlsConf)\n}\ncc, _ := grpc.NewClient(target, grpc.WithTransportCredentials(creds))","handlingStrategy":"fallback","validationCode":"// Choose creds by environment so ALTS is only used on GCP\nfunc pickCreds(onGCP bool) credentials.TransportCredentials {\n    if onGCP {\n        return alts.NewClientCreds(alts.DefaultClientOptions())\n    }\n    return credentials.NewTLS(&tls.Config{ServerName: server})\n}","typeGuard":null,"tryCatchPattern":"if errors.Is(err, alts.ErrUntrustedPlatform) {\n    // not on GCP; fall back to TLS or fail explicitly\n    creds = credentials.NewTLS(tlsConf)\n}","preventionTips":["Gate ALTS behind a GCP environment check; prefer TLS off-GCP.","In ALTS tests, force vmOnGCP=true via the internal test package.","Document per-environment credential selection in service config."],"tags":["alts","security","gcp","grpc-go"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}