Google Cloud SDK for Rust
Async gRPC clients for every Google Cloud API, generated from googleapis with Tonic, and the glue to authenticate them and your own services.
The library provides:
- tonic clients and prost types for every Google API, each behind its own feature;
- a tower middleware that attaches Google credentials to every request, with authentication from the official google-cloud-auth crate;
- service-to-service authentication with Google ID tokens: minting them for Cloud Run and IAP, a reqwest middleware, and an axum/tower layer that verifies them;
tls-roots(native-tls) andtls-webpki-roots(rustls) options for the connections.
This is not an official Google project.
gcloud-sdk and the official Google Cloud Rust SDK
Google now publishes an official Google Cloud Rust SDK:
high-level clients for most Google Cloud services and google-cloud-auth for credentials.
Since 0.33 gcloud-sdk builds on it.
Authentication comes from Google
Every access token and ID token is minted by google-cloud-auth.
Credential formats, new credential sources and security fixes come from Google, and gcloud-sdk no longer maintains a second copy of them.
It also covers cases the old token sources of gcloud-sdk did not:
- workload identity federation with executable sources, workforce pools, and AWS without the AWS SDK;
- impersonation with scopes, delegates and token lifetime;
- quota projects (
x-goog-user-project,GOOGLE_CLOUD_QUOTA_PROJECT) and universe domains; - token refresh before expiry, with retries.
The REST clients are removed for the same reason: the official crates cover them, see REST APIs moved to the official SDK.
The gaps gcloud-sdk fills
The official SDK still leaves gaps, and closes them slowly. As of October 2026:
- Raw gRPC access. The official crates expose no tonic clients or prost types and take no channel or tower layers of your own. gcloud-sdk generates a tonic client for every API in googleapis, so any method of any API is available as soon as it appears in the protos.
- Data-plane APIs. Bigtable, Firestore (including
Listen) and Datastore are not published as official crates, Spanner is pre-1.0, and BigQuery Storage Read sits behind an unstable cfg. - Streaming. Bidirectional and server streaming calls work as tonic streams, including the ones the official SDK does not provide:
Firestore
Listen, BigtableReadRows, Speech v1StreamingRecognize, and any streaming method of an API that has no official crate, or no gRPC transport in its official crate. - Your own tower stack. The clients are plain tonic clients over a tower service, so you can add your own layers, timeouts and channels.
- native-tls. The official SDK supports rustls only and declined native-tls in googleapis/google-cloud-rust#4316.
With
tls-roots, gcloud-sdk uses native-tls for the gRPC channels and for the token requests ofgoogle-cloud-auth. Be aware that if another dependency enables thehttp3feature of reqwest, the default reqwest backend is rustls again, and the token requests use it.
Opinionated integrations
gcloud-sdk makes choices the official SDK leaves to you:
VerifyIdTokenLayerverifies Google ID tokens in axum and tonic servers, with typed claims and anauthorizecheck;GoogleAuthMiddlewareLayerandGoogleAuthReqwestMiddlewareattach credentials to tonic and reqwest calls;- the higher-level crates listed in High-level APIs build on these clients: Firestore, BigQuery, Secret Manager, KMS, Cloud Trace.
Which one to use
- The official crates, when a high-level client exists for your service and you need nothing from the list above.
- gcloud-sdk, for raw gRPC access, the data-plane APIs above, streaming, your own tower layers, native-tls, or service-to-service authentication.
The two combine in one application. The authentication of gcloud-sdk is google-cloud-auth, re-exported as gcloud_sdk::google_cloud_auth,
so one Credentials serves the official clients and the gcloud-sdk clients.
Migrating from 0.32
0.33 is a breaking release: see MIGRATING.md for the API mapping, removed features, behaviour changes and the REST APIs that moved to the official crates.
Getting started
Features
Each Google API is behind its own feature, and you must enable the ones you use.
For example, for Cloud Pub/Sub write features = ["google-pubsub-v1"] in Cargo.toml.
The feature name is the proto package name with periods replaced by hyphens: google.pubsub.v1 is google-pubsub-v1.
The full list is on docs.rs, and in the # Google API features section of gcloud-sdk/Cargo.toml.
The library features:
tls-roots: default, native-tls with the system roots;tls-webpki-roots: rustls with the webpki roots;auth-default-crypto: default, the aws-lc-rs crypto ofgoogle-cloud-auth;jwt-aws-lc-rs(default),jwt-rust-cryptoandjwt-custom-provider: the crypto of the ID token verifier, see JWT crypto provider;id-token-verify,axum,reqwest-middleware: service-to-service authentication.
Example for gRPC
[]
= { = "0.33", = ["google-firestore-v1"] }
= { = "1", = ["macros", "rt-multi-thread"] }
use FirestoreClient;
use ListDocumentsRequest;
use *;
let google_project_id = detect_google_project_id
.await
.expect;
let cloud_resource_prefix = format!;
// The Application Default Credentials, for the cloud-platform scope
let firestore_client: =
from_function
.await?;
let response = firestore_client
.get
.list_documents
.await?;
Full example available here. More examples are located here.
Crypto providers
google-cloud-auth signs service account JWTs with a rustls CryptoProvider.
With the default features it uses aws-lc-rs.
With default-features = false, enable a TLS feature and install a provider yourself before building credentials,
with the same rustls version as google-cloud-auth (0.23):
[]
= { = "0.33", = false, = ["tls-roots", "google-firestore-v1"] }
= { = "0.23", = ["ring"] }
default_provider
.install_default
.expect;
Without a provider, the constructors that use the ADC return ErrorKind::CryptoProviderMissing when the ADC signs locally,
with a service account key used directly or as the source of an impersonation:
from_function, from_function_with_scopes and the other from_function* without credentials,
GoogleAuthHeaders::from_adc, GoogleAuthHeaders::from_adc_with_scopes and GoogleAuthHeaders::id_token_from_adc.
For a service account key that is not the ADC, GoogleAuthHeaders::from_service_account_key runs the same check
and returns the same error:
let key: Value = from_str?;
let auth_headers = from_service_account_key.await?;
Credentials you build yourself are not checked: the ones passed to from_function_with_credentials*, with_credentials*,
GoogleAuthHeaders::from(..), and the source credentials of GoogleAuthHeaders::id_token_impersonating.
Install the provider before building them, otherwise their refresh task panics.
The same call fixes this error, which appears when more than one rustls provider is compiled into your application:
no process-level CryptoProvider available -- call CryptoProvider::install_default() before this point
Google authentication
The library authenticates with google-cloud-auth. GoogleApi::from_function uses the Application Default Credentials (ADC)
for the https://www.googleapis.com/auth/cloud-platform scope. ADC looks for credentials in the following places, preferring the first location found:
- a JSON file whose path is in the
GOOGLE_APPLICATION_CREDENTIALSenvironment variable; - the file
gcloud auth application-default loginwrites; - the metadata server on Compute Engine, GKE, Cloud Run, etc.
The JSON file can be a service account key, user credentials, impersonated service account credentials or a workload identity federation config.
Credentials must be built inside a Tokio runtime.
Custom scopes
from_function_with_scopes() takes the scopes instead of from_function():
let client: =
from_function_with_scopes
.await?;
Custom credentials
from_function_with_credentials() takes any Credentials built with google-cloud-auth, for example a service account key that is not the ADC:
use service_account;
let credentials = new.build?;
let client: =
from_function_with_credentials
.await?;
For tokens from your own source, implement google_cloud_auth::credentials::CredentialsProvider and wrap it with Credentials::from(..).
The same Credentials work with the official Google Cloud Rust clients.
Workload identity federation
Workload identity federation gives "keyless" access from other clouds and CI systems. Point GOOGLE_APPLICATION_CREDENTIALS
at the external_account config from gcloud iam workload-identity-pools create-cred-config. The supported sources:
- file: an OIDC or SAML token in a text or JSON file;
- URL: an OIDC or SAML token from a URL, for example in GitHub Actions;
- AWS: the
AWS_ACCESS_KEY_IDenvironment keys, else EC2 IMDS (IMDSv2 when the config has a session token URL). ECS task roles,~/.awsprofiles and SSO are not supported; - executable: a command that prints the token. It runs only with
GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES=1.
Workforce identity pools and service account impersonation in the config work as well.
Local development
Don't confuse gcloud auth login with gcloud auth application-default login for local development,
since the first authorizes only the gcloud tool to access the Cloud Platform.
The latter obtains user access credentials via a web flow and puts them in the well-known location for ADC.
So to work for local development you need to use gcloud auth application-default login.
gcloud auth application-default login --impersonate-service-account=... runs the code as a service account instead.
Routing headers
Some of the APIs (notably KMS, Artifact Registry and others) require additional headers such as x-goog-request-params.
You can find an example how to handle it here
Service-to-service authentication
The library supports Google-signed ID tokens on both sides of a call between services:
- minting them to call Cloud Run, Cloud Run functions and services behind Identity-Aware Proxy (IAP);
- attaching them to gRPC and HTTP requests;
- verifying them in the service that receives the call (
id-token-verifyfeature); - protecting an axum service (
axumfeature) and calling it with reqwest (reqwest-middlewarefeature).
Full examples: axum service, reqwest client. examples/id-token mints and verifies a token with the core API only, and is the end-to-end check of the keyless CI workflow.
Calling a Cloud Run or IAP service
GoogleAuthHeaders::id_token_from_adc mints ID tokens for one audience:
- the URL of a Cloud Run service, or a custom audience configured for it;
- the OAuth client ID of a resource behind IAP.
Google ID tokens are valid for one hour. google-cloud-auth caches the token and refreshes it before it expires.
gRPC (for example a tonic service on Cloud Run), with the default features:
use ;
let audience = new;
let id_tokens = id_token_from_adc.await?;
let orders_client: =
from_function_with_middleware
.await?;
HTTP with reqwest-middleware feature:
= { = "0.33", = ["reqwest-middleware"] }
= "0.13"
= "0.5"
use GoogleAuthReqwestMiddleware;
let client = new
.with
.build;
let response = client
.get
.send
.await?;
Full example available here.
The middleware constructors take GoogleAuthHeaders or Arc<GoogleAuthHeaders>.
For access tokens of the ADC instead of ID tokens, for example to call Google APIs over HTTP,
use GoogleAuthHeaders::from_adc() or GoogleAuthHeaders::from_adc_with_scopes(..).
Without the reqwest-middleware feature, id_tokens.headers().await? gives the headers, authorization among them, for any HTTP client.
Which credentials work
GoogleAuthHeaders::id_token_from_adc mints with the identity of the ADC:
- service account key file: as that service account;
- metadata server (Cloud Run, GKE, Compute Engine, etc.): as the service account attached to the workload;
gcloud auth application-default login --impersonate-service-account=...and workload identity federation with service account impersonation: as the impersonated service account.
These credentials hold no service account and cannot mint an ID token for an audience,
so id_token_from_adc returns ErrorKind::IdTokenNeedsImpersonation for them:
- user credentials from
gcloud auth application-default login(AuthorizedUser); - workforce identity federation users (
ExternalAccountAuthorizedUser); - workload identity federation without service account impersonation (
ExternalAccount); - Google Distributed Cloud Hosted service accounts (
GdchServiceAccount).
Use GoogleAuthHeaders::id_token_impersonating with any credentials but the last to mint ID tokens of a service account through
IAM Credentials API:
use Builder as CredentialsBuilder;
use ;
let id_tokens = id_token_impersonating
.await?;
The caller needs roles/iam.serviceAccountOpenIdTokenCreator on that service account.
This is also the way for local development, using your own gcloud auth application-default login credentials.
For a key file or a metadata server that is not the ADC, build the ID token credentials with google_cloud_auth::credentials::idtoken
and pass them to GoogleAuthHeaders::from(..).
Receiving and verifying tokens
IdTokenVerifier from id-token-verify feature checks:
- RS256 signature with Google keys from
https://www.googleapis.com/oauth2/v3/certs; issis Google, andaudis the audience of your service;exp,nbfandiat, with 30 seconds of leeway.
The keys are cached for the max-age of the response. A token signed with an unknown key ID refetches them,
at most once every 30 seconds. When a fetch fails, the cached keys stay in use until their max-age passes.
= { = "0.33", = ["id-token-verify"] }
The verifier fetches the keys over HTTPS, so it needs tls-roots or tls-webpki-roots, or a TLS feature of reqwest in your application.
Without one, every key fetch fails at runtime with KeysUnavailable.
use ;
use IdTokenAudience;
let verifier = new?;
match verifier.verify.await
IdTokenVerifier::with_keys_source takes the keys from your own IdTokenKeysSource instead,
for example a locally generated RSA key in tests.
The verifier checks signatures with the JWT crypto provider of the library features.
Protecting an axum service
VerifyIdTokenLayer from axum feature verifies the bearer token of every request:
- 401 for a missing or invalid token;
- 403 when the token is valid, but your
authorizecheck refuses the caller; - 503 when Google keys are not available.
Handlers receive the verified claims as VerifiedIdToken:
= { = "0.33", = ["id-token-verify", "axum"] }
= "0.8"
use Arc;
use get;
use Router;
use ;
use IdTokenAudience;
let verifier = new;
let billing = new;
let app = new
.route
.layer;
async
The layer is a tower layer, so it works the same way for tonic servers.
Full example available here.
JWT crypto provider
IdTokenVerifier verifies JWTs with jsonwebtoken, which needs a crypto provider. The library has a feature for each:
jwt-aws-lc-rs: default feature, uses aws-lc-rs, which is built from C sources and needs a C compiler;jwt-rust-crypto: the pure Rust alternative, uses the crates of RustCrypto;jwt-custom-provider: your application installs its ownjsonwebtokenprovider withCryptoProvider::install_defaultbefore it verifies a token.
With default-features = false and id-token-verify, enable one of them, otherwise the build fails.
With both enabled, aws-lc-rs is used.
The library installs the provider of the enabled feature as the process default of jsonwebtoken, unless your application installed one before.
These features choose the crypto of the verifier only. auth-default-crypto and tls-webpki-roots build aws-lc-rs for google-cloud-auth and rustls anyway.
High-level APIs
Sometimes using proto generated APIs are tedious and cumbersome, so you may need to introduce facade APIs on top of them:
- firestore - to work with Firestore;
- bigquery - to work with BigQuery;
- secret-vault - to read secrets from Google Secret Manager;
- kms-aead - envelope encryption using Google KMS and Ring AEAD;
- opentelemetry-gcloud-trace - Google Cloud Trace support for OpenTelemetry project.
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Authors
- Abdulla Abdurakhmanov
The library was started as a fork of mechiru/googapis and mechiru/gouth libraries, but now includes much more:
- Tower-based middleware layer that hides the complexity of working with credentials and TLS behind async clients;
- gRPC clients for every Google API, with a feature for each;
- Improved observability with tracing and measuring execution time of endpoints;
- Uses synchronisation primitives (such as Mutex) from tokio everywhere and has direct dependencies to tokio runtime;
- Security-related protocol extensions for Google Secret Manager and KMS;
- Service-to-service authentication with Google ID tokens: minting them, verifying them, a reqwest middleware and an axum layer.