{"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/0c51461d27177d997e14c642fe18c11668fc09a3/credentials/alts/alts.go#L53-L89","documentation":"Thrown by matchersFromPermissions in its default switch case when a Permission proto's Rule oneof is set to a variant that gRPC RBAC does not handle. The supported permission types are: AndRules, OrRules, Any, Header, UrlPath, DestinationIp, DestinationPort, NotRule, Metadata, and RequestedServerName. Any other variant (e.g., a new Envoy Permission type like a hypothetical destination_cluster or a future extension) triggers this error, causing the entire RBAC engine construction to fail.","triggerScenarios":"A control plane sends an RBAC policy whose permissions include a type not implemented by the version of grpc-go in use. For example, a newer go-control-plane proto adds a Permission variant (like a GraphQL or WebSocket permission) that this version's matchersFromPermissions switch does not enumerate. The NewChainEngine call propagates the error, and the xDS resource is NACKed.","commonSituations":"Version skew between the control plane's go-control-plane and grpc-go's bundled version. A new Envoy RBAC feature deployed via the control plane before grpc-go adds support. A custom proto extension adding a non-standard Permission variant.","solutions":["Upgrade grpc-go to a version whose matchersFromPermissions supports the permission type the control plane sends.","Remove the unsupported permission type from the RBAC policy on the control plane and use only supported types (rule, and_rules, or_rules, any, header, url_path, destination_ip, destination_port, not_rule, metadata, requested_server_name).","If the permission type is genuinely unsupported by design, restructure the policy to avoid it — e.g., replace a destination port rule with an equivalent header or URL path match."],"exampleFix":"// before: control plane sends an unsupported permission variant\npermissions:\n  - someNewType: {cluster: \"my-cluster\"}\n\n// after: use a supported permission type\npermissions:\n  - any: true","handlingStrategy":"validation","validationCode":"// Validate all permission types are supported before building the engine:\nvar supportedPerms = map[reflect.Type]bool{}\nfunc init() {\n    // enumerate supported permission oneof types\n}\nfunc validatePermissions(perms []*v3rbacpb.Permission) error {\n    for _, p := range perms {\n        switch p.GetRule().(type) {\n        case *v3rbacpb.Permission_AndRules:\n            if err := validatePermissions(p.GetAndRules().GetRules()); err != nil { return err }\n        case *v3rbacpb.Permission_OrRules:\n            if err := validatePermissions(p.GetOrRules().GetRules()); err != nil { return err }\n        case *v3rbacpb.Permission_Any, *v3rbacpb.Permission_Header,\n             *v3rbacpb.Permission_UrlPath, *v3rbacpb.Permission_DestinationIp,\n             *v3rbacpb.Permission_DestinationPort, *v3rbacpb.Permission_NotRule,\n             *v3rbacpb.Permission_Metadata, *v3rbacpb.Permission_RequestedServerName:\n            // supported\n        default:\n            return fmt.Errorf(\"unsupported permission type %T\", p.GetRule())\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pin grpc-go and go-control-plane to compatible versions.","When upgrading the control plane, diff the Permission proto to check for new oneof variants.","Validate RBAC policies on the control plane against the data plane's supported feature set before sending."],"tags":["xds","rbac","grpc","permission","unsupported","version-skew"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}