feat: support full-format identity tokens on GCE - #681
Conversation
Adds an optional $idTokenFormat constructor argument to GCECredentials. When a target audience is set, passing 'full' appends '&format=full' to the metadata server identity request so the returned ID token includes the full VM instance payload (for example, the authorized party's email), matching the behavior of the Python auth library. The value is validated to 'standard' or 'full'. Fixes googleapis#526
|
This works, but it's interesting because all our auth libraries other than Python (Go, NodeJS, C#, Java, Ruby, Rust, and C++) do NOT support this, and instead align with the PHP auth library's current behavior. And even Python doesn't support this, it just has Could you tell me the use-case that requires this? Are you getting the ID token with Here's a way this can be done with our library without having to implement this parameter: $gce = new GCECredentials(targetAudience: 'https://my-service.run.app');
$defaultHandler = HttpHandlerFactory::build();
$customHttpHandler = function (RequestInterface $request) use ($defaultHandler): ResponseInterface {
$uri = $request->getUri();
// Append format=full to the existing query string for identity token requests
if (strpos($uri->getPath(), '/identity') !== false) {
$query = $uri->getQuery();
$uri = $uri->withQuery($query . ($query ? '&' : '') . 'format=full');
$request = $request->withUri($uri);
}
// Pass the rewritten request to the standard HTTP transport handler
return $defaultHandler($request);
};
$tokenData = $gce->fetchAuthToken($customHttpHandler);
$fullJwt = $tokenData['id_token']; // Contained full payload (email, project, zone, etc.) |
|
Good question @bshaffer — I went and checked the other libraries before answering, and the picture is a bit different from what we both might have assumed:
So among Python, Node, Go, Java, and C#, PHP is currently the only one without a way to get the full-format token — and the opt-in shape in this PR is the same design Java, C#, and the new Go library settled on, which I'd agree beats Python/Node hardcoding it. The use case is the one from #526: service-to-service calls on Cloud Run, where the receiving service verifies the incoming ID token and authorizes on the calling service account's email claim, which the standard format omits. We're not reading it back through The handler workaround does work, but one subtle issue pushed me toward a first-class option: Happy to also add the licenses flag for parity with Java/C#/Go, or adjust the parameter shape to whatever fits this library's conventions best. |
Fixes #526.
On GCE/Cloud Run, the identity token returned by the metadata server omits the full payload (for example, the authorized party's email) unless
format=fullis requested. The Python auth library already does this; this brings PHP in line.Adds an optional, backward-compatible
$idTokenFormatargument to theGCECredentialsconstructor. When a target audience is set, passing'full'appends&format=fullto the metadata identity request:The value is validated to
standardorfull. Existing callers are unaffected (the default preserves the current request). Scoped toGCECredentials; exposing the option throughApplicationDefaultCredentials::getIdTokenCredentialsis a natural follow-up kept out of this PR to keep it to one subject.Unit tests cover the appended query string and the validation error.