[GH-ISSUE #952] Signed URLs: Unable to authenticate with AnonymousCredentials #151

Closed
opened 2026-03-03 12:08:44 +03:00 by kerem · 15 comments
Owner

Originally created by @Sorarinu on GitHub (Oct 15, 2022).
Original GitHub issue: https://github.com/fsouza/fake-gcs-server/issues/952

Hi, everyone!

When I generate Signed URLs using service-account.json issued from GCP the authentication succeeds, but when I try to use AnonymousCredentials() as credentials it does not work.

import datetime
import requests

from google.cloud import storage
from google.cloud.storage.blob import Blob
from google.oauth2 import service_account
from google.api_core.client_options import ClientOptions
from google.auth.credentials import AnonymousCredentials

def _get_client():
    _http = requests.Session()
    _http.verify = False

    # this works.
    # credentials = service_account.Credentials.from_service_account_file("path/to/service-account.json")

    return storage.Client(
        # credentials=credentials,
        credentials=AnonymousCredentials(),
        project="fake-gcs",
        _http=_http,
        client_options=ClientOptions(api_endpoint="http://fake-gcs:4443"),  # accsess from docker network
    )

def _replace_gcs_url(url):
    return url.replace("https://storage.googleapis.com/", "http://localhost:4443/")

blob = Blob.from_string("gs://path/to/resource", client=_get_client())
url = blob.generate_signed_url(
    version="v4",
    expiration=datetime.timedelta(
        seconds=60,
    ),
    method="GET",
)

url = _replace_gcs_url(url)

docker logs:

app                   | AttributeError: you need a private key to sign credentials.the credentials you are currently using <class 'google.auth.credentials.AnonymousCredentials'> just contains a token. see https://googleapis.dev/python/google-api-core/latest/auth.html#setting-up-a-service-account for more details.

We would like to avoid getting GCS service-account.json in the local development environment as much as possible.
Is there a better way to do this?

Originally created by @Sorarinu on GitHub (Oct 15, 2022). Original GitHub issue: https://github.com/fsouza/fake-gcs-server/issues/952 Hi, everyone! When I generate Signed URLs using `service-account.json` issued from GCP the authentication succeeds, but when I try to use `AnonymousCredentials()` as credentials it does not work. ```python import datetime import requests from google.cloud import storage from google.cloud.storage.blob import Blob from google.oauth2 import service_account from google.api_core.client_options import ClientOptions from google.auth.credentials import AnonymousCredentials def _get_client(): _http = requests.Session() _http.verify = False # this works. # credentials = service_account.Credentials.from_service_account_file("path/to/service-account.json") return storage.Client( # credentials=credentials, credentials=AnonymousCredentials(), project="fake-gcs", _http=_http, client_options=ClientOptions(api_endpoint="http://fake-gcs:4443"), # accsess from docker network ) def _replace_gcs_url(url): return url.replace("https://storage.googleapis.com/", "http://localhost:4443/") blob = Blob.from_string("gs://path/to/resource", client=_get_client()) url = blob.generate_signed_url( version="v4", expiration=datetime.timedelta( seconds=60, ), method="GET", ) url = _replace_gcs_url(url) ``` docker logs: ``` app | AttributeError: you need a private key to sign credentials.the credentials you are currently using <class 'google.auth.credentials.AnonymousCredentials'> just contains a token. see https://googleapis.dev/python/google-api-core/latest/auth.html#setting-up-a-service-account for more details. ``` We would like to avoid getting GCS service-account.json in the local development environment as much as possible. Is there a better way to do this?
kerem closed this issue 2026-03-03 12:08:44 +03:00
Author
Owner

@fsouza commented on GitHub (Oct 15, 2022):

Hey, are you saying that generating the URL fails or sending a request to the generated URL fails?

The reason I ask is because the server (fake or real) is not involved in generating URLs, it happens within the client.

<!-- gh-comment-id:1279739691 --> @fsouza commented on GitHub (Oct 15, 2022): Hey, are you saying that generating the URL fails or sending a request to the generated URL fails? The reason I ask is because the server (fake or real) is not involved in generating URLs, it happens within the client.
Author
Owner

@Sorarinu commented on GitHub (Oct 15, 2022):

It appears that the URL generation is failing.

The reason I ask is because the server (fake or real) is not involved in generating URLs, it happens within the client.

As you pointed out, the URL generation and authentication are done by the google-cloud-storage client, so it was a mistake to inquire with fake-gcs-server 🙇

<!-- gh-comment-id:1279744749 --> @Sorarinu commented on GitHub (Oct 15, 2022): It appears that the URL generation is failing. > The reason I ask is because the server (fake or real) is not involved in generating URLs, it happens within the client. As you pointed out, the URL generation and authentication are done by the google-cloud-storage client, so it was a mistake to inquire with fake-gcs-server 🙇
Author
Owner

@fsouza commented on GitHub (Oct 15, 2022):

Yeah I think the client will simply not work with AnonymousCredentials. Perhaps you can have some process that generates a valid-but-fake service-account.json? IIRC, that's how I used to do it in a previous job.

<!-- gh-comment-id:1279747929 --> @fsouza commented on GitHub (Oct 15, 2022): Yeah I think the client will simply not work with AnonymousCredentials. Perhaps you can have some process that generates a valid-but-fake service-account.json? IIRC, that's how I used to do it in a previous job.
Author
Owner

@Sorarinu commented on GitHub (Oct 15, 2022):

I will try to generate valid-but-fake service-account.json and see if the URL generation succeeds.

<!-- gh-comment-id:1279751358 --> @Sorarinu commented on GitHub (Oct 15, 2022): I will try to generate valid-but-fake service-account.json and see if the URL generation succeeds.
Author
Owner

@Sorarinu commented on GitHub (Oct 15, 2022):

I tried passing dummy information based on the format of valid service-account.json, and it succeeded in generating a Signed URL!
Thank you for your help!

<!-- gh-comment-id:1279755406 --> @Sorarinu commented on GitHub (Oct 15, 2022): I tried passing dummy information based on the format of valid service-account.json, and it succeeded in generating a Signed URL! Thank you for your help!
Author
Owner

@ddelange commented on GitHub (Dec 12, 2022):

@Sorarinu could you post your mock json here?

<!-- gh-comment-id:1346187435 --> @ddelange commented on GitHub (Dec 12, 2022): @Sorarinu could you post your mock json here?
Author
Owner

@ddelange commented on GitHub (Dec 12, 2022):

I'm currently stuck creating a valid fake json:

{"client_email": "a@bc.de", "token_uri": "foo", "private_key": "bar"}

raises:

  File "/pypicloud/pypicloud/storage/gcs.py", line 139, in _get_storage_client
    client = storage.Client.from_service_account_json(
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/client/__init__.py", line 109, in from_service_account_json
    return cls.from_service_account_info(credentials_info, *args, **kwargs)
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/client/__init__.py", line 76, in from_service_account_info
    credentials = service_account.Credentials.from_service_account_info(info)
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/oauth2/service_account.py", line 224, in from_service_account_info
    signer = _service_account_info.from_dict(
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/auth/_service_account_info.py", line 58, in from_dict
    signer = crypt.RSASigner.from_service_account_info(data)
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/auth/crypt/base.py", line 113, in from_service_account_info
    return cls.from_string(
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/auth/crypt/_cryptography_rsa.py", line 133, in from_string
    private_key = serialization.load_pem_private_key(
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/cryptography/hazmat/primitives/serialization/base.py", line 22, in load_pem_private_key
    return ossl.load_pem_private_key(data, password)
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 921, in load_pem_private_key
    return self._load_key(
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1189, in _load_key
    self._handle_key_loading_error()
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1248, in _handle_key_loading_error
    raise ValueError(
ValueError: ('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [_OpenSSLErrorWithText(code=503841036, lib=60, reason=524556, reason_text=b'error:1E08010C:DECODER routines::unsupported')])
<!-- gh-comment-id:1346220261 --> @ddelange commented on GitHub (Dec 12, 2022): I'm currently [stuck](https://github.com/stevearc/pypicloud/actions/runs/3674689977/jobs/6213213606#step:4:2885) creating a valid fake json: ```json {"client_email": "a@bc.de", "token_uri": "foo", "private_key": "bar"} ``` raises: ```pytb File "/pypicloud/pypicloud/storage/gcs.py", line 139, in _get_storage_client client = storage.Client.from_service_account_json( File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/client/__init__.py", line 109, in from_service_account_json return cls.from_service_account_info(credentials_info, *args, **kwargs) File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/client/__init__.py", line 76, in from_service_account_info credentials = service_account.Credentials.from_service_account_info(info) File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/oauth2/service_account.py", line 224, in from_service_account_info signer = _service_account_info.from_dict( File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/auth/_service_account_info.py", line 58, in from_dict signer = crypt.RSASigner.from_service_account_info(data) File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/auth/crypt/base.py", line 113, in from_service_account_info return cls.from_string( File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/auth/crypt/_cryptography_rsa.py", line 133, in from_string private_key = serialization.load_pem_private_key( File "/pypicloud/.tox/py38/lib/python3.8/site-packages/cryptography/hazmat/primitives/serialization/base.py", line 22, in load_pem_private_key return ossl.load_pem_private_key(data, password) File "/pypicloud/.tox/py38/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 921, in load_pem_private_key return self._load_key( File "/pypicloud/.tox/py38/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1189, in _load_key self._handle_key_loading_error() File "/pypicloud/.tox/py38/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1248, in _handle_key_loading_error raise ValueError( ValueError: ('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [_OpenSSLErrorWithText(code=503841036, lib=60, reason=524556, reason_text=b'error:1E08010C:DECODER routines::unsupported')]) ```
Author
Owner

@fsouza commented on GitHub (Dec 12, 2022):

You can generate an actual file (with a service account) and revoke it, or use SSL to generate a private key.

<!-- gh-comment-id:1346529844 --> @fsouza commented on GitHub (Dec 12, 2022): You can generate an actual file (with a service account) and revoke it, or use SSL to generate a private key.
Author
Owner

@ddelange commented on GitHub (Dec 12, 2022):

yeah was looking into this but failing 😅 I'm writing tests for a storage backend I dont have access to (s3 guy here), so I'm already just really thankful for the existence of this repo! Will continue the fiddle

<!-- gh-comment-id:1346538048 --> @ddelange commented on GitHub (Dec 12, 2022): yeah was looking into this but failing 😅 I'm writing tests for a storage backend I dont have access to (s3 guy here), so I'm already just really thankful for the existence of this repo! Will continue the fiddle
Author
Owner

@ddelange commented on GitHub (Dec 13, 2022):

@fsouza I have a valid PEM for presigning URLs now, but the dummy token_uri from the service account used for JWT auth needs to point to a functional endpoint. does fake-gcs-server provide it?

import tempfile
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
from google.cloud import storage
from google.oauth2 import service_account
from google.api_core.client_options import ClientOptions
from google.auth.credentials import AnonymousCredentials

config_file = tempfile.mktemp()
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
pem = private_key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.TraditionalOpenSSL,
    encryption_algorithm=serialization.NoEncryption(),
).decode("utf-8")
with open(self._config_file, "w", encoding="utf-8") as ofile:
    json.dump(
        {
            "client_email": "a@bc.de",
            "token_uri": "http://fake-gcs-server:4443/oauth2/v3/certs",  # 404
            "private_key": pem,
        },
        ofile,
    )

credentials = service_account.Credentials.from_service_account_file(config_file)
client = storage.Client(
    credentials=credentials,
    # credentials=AnonymousCredentials(),
    project="test",
    client_options=ClientOptions(api_endpoint="http://fake-gcs-server:4443"),
)

will give a 404:

  File "/pypicloud/pypicloud/storage/gcs.py", line 151, in get_bucket
    if not bucket.exists():
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/storage/bucket.py", line 900, in exists
    client._get_resource(
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/storage/client.py", line 372, in _get_resource
    return self._connection.api_request(
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/storage/_http.py", line 72, in api_request
    return call()
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/api_core/retry.py", line 349, in retry_wrapped_func
    return retry_target(
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/api_core/retry.py", line 191, in retry_target
    return target()
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/_http/__init__.py", line 482, in api_request
    response = self._make_request(
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/_http/__init__.py", line 341, in _make_request
    return self._do_request(
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/_http/__init__.py", line 379, in _do_request
    return self.http.request(
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/auth/transport/requests.py", line 545, in request
    self.credentials.before_request(auth_request, method, url, request_headers)
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/auth/credentials.py", line 134, in before_request
    self.refresh(request)
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/oauth2/service_account.py", line 429, in refresh
    access_token, expiry, _ = _client.jwt_grant(
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/oauth2/_client.py", line 289, in jwt_grant
    response_data = _token_endpoint_request(
  File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/oauth2/_client.py", line 250, in _token_endpoint_request
    response_status_ok, response_data, retryable_error = _token_endpoint_request_no_throw(
...
urllib3.connectionpool: DEBUG: http://fake-gcs-server:4443 "POST /oauth2/v3/certs HTTP/1.1" 404 59

do you know how to get around it? I don't have creds to talk to googleapis.com (ref)

<!-- gh-comment-id:1347919894 --> @ddelange commented on GitHub (Dec 13, 2022): @fsouza I have a valid PEM for presigning URLs now, but the dummy token_uri from the service account used for JWT auth needs to point to a functional endpoint. does fake-gcs-server provide it? ```python import tempfile from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives import serialization from google.cloud import storage from google.oauth2 import service_account from google.api_core.client_options import ClientOptions from google.auth.credentials import AnonymousCredentials config_file = tempfile.mktemp() private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) pem = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption(), ).decode("utf-8") with open(self._config_file, "w", encoding="utf-8") as ofile: json.dump( { "client_email": "a@bc.de", "token_uri": "http://fake-gcs-server:4443/oauth2/v3/certs", # 404 "private_key": pem, }, ofile, ) credentials = service_account.Credentials.from_service_account_file(config_file) client = storage.Client( credentials=credentials, # credentials=AnonymousCredentials(), project="test", client_options=ClientOptions(api_endpoint="http://fake-gcs-server:4443"), ) ``` will [give](https://github.com/stevearc/pypicloud/actions/runs/3683504689/jobs/6232158262#step:4:3073) a 404: ```pytb File "/pypicloud/pypicloud/storage/gcs.py", line 151, in get_bucket if not bucket.exists(): File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/storage/bucket.py", line 900, in exists client._get_resource( File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/storage/client.py", line 372, in _get_resource return self._connection.api_request( File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/storage/_http.py", line 72, in api_request return call() File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/api_core/retry.py", line 349, in retry_wrapped_func return retry_target( File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/api_core/retry.py", line 191, in retry_target return target() File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/_http/__init__.py", line 482, in api_request response = self._make_request( File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/_http/__init__.py", line 341, in _make_request return self._do_request( File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/cloud/_http/__init__.py", line 379, in _do_request return self.http.request( File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/auth/transport/requests.py", line 545, in request self.credentials.before_request(auth_request, method, url, request_headers) File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/auth/credentials.py", line 134, in before_request self.refresh(request) File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/oauth2/service_account.py", line 429, in refresh access_token, expiry, _ = _client.jwt_grant( File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/oauth2/_client.py", line 289, in jwt_grant response_data = _token_endpoint_request( File "/pypicloud/.tox/py38/lib/python3.8/site-packages/google/oauth2/_client.py", line 250, in _token_endpoint_request response_status_ok, response_data, retryable_error = _token_endpoint_request_no_throw( ... urllib3.connectionpool: DEBUG: http://fake-gcs-server:4443 "POST /oauth2/v3/certs HTTP/1.1" 404 59 ``` do you know how to get around it? I don't have creds to talk to googleapis.com ([ref](https://cloud.google.com/endpoints/docs/openapi/authenticating-users-google-id))
Author
Owner

@fsouza commented on GitHub (Dec 13, 2022):

Hmm, fake-gcs-server doesn't have that endpoint because it only implements the Storage API. Curious on why you can't use AnonymousCredentials? Can you clarify the use case a bit more?

<!-- gh-comment-id:1348505532 --> @fsouza commented on GitHub (Dec 13, 2022): Hmm, fake-gcs-server doesn't have that endpoint because it only implements the Storage API. Curious on why you can't use AnonymousCredentials? Can you clarify the use case a bit more?
Author
Owner

@ddelange commented on GitHub (Dec 13, 2022):

In https://github.com/stevearc/pypicloud/pull/320 I'm switching from mocked client classes to fake-gcs-server and the real client. Mainly because we missed a bug that would've been caught with the latter, and was missed because mocks weren't properly updated.

This test (testing that generating presigned url works) won't work with AnonymousCredentials (this issue), so in test setUp I passed the PEM.

But now bucket.exists() (which happens during init of pypicloud.storage.gcs.GoogleCloudStorage) won't work, because the token_uri is fake. That's the traceback in my last comment above. But probably this fake token_uri will break all other calls as well.

So long story short: we have a test that mixes interacting with fake-gcs-server (only works with AnonymousCredentials) and generating presigned url (does not work with AnonymousCredentials).

<!-- gh-comment-id:1348575546 --> @ddelange commented on GitHub (Dec 13, 2022): In https://github.com/stevearc/pypicloud/pull/320 I'm switching from mocked client classes to fake-gcs-server and the real client. Mainly because we missed a bug that would've been caught with the latter, and was missed because mocks weren't properly updated. [This test](https://github.com/ddelange/pypicloud/blob/b1b4046a6fc42ac9b68a9576d362982e256580ac/tests/test_storage.py#L444) (testing that [generating](https://github.com/ddelange/pypicloud/blob/b1b4046a6fc42ac9b68a9576d362982e256580ac/pypicloud/storage/gcs.py#L199) presigned url works) won't work with `AnonymousCredentials` (this issue), so in test setUp I passed the PEM. But now `bucket.exists()` (which [happens](https://github.com/ddelange/pypicloud/blob/b1b4046a6fc42ac9b68a9576d362982e256580ac/pypicloud/storage/gcs.py#L151) during init of `pypicloud.storage.gcs.GoogleCloudStorage`) won't work, because the `token_uri` is fake. That's the traceback in my last comment above. But probably this fake `token_uri` will break all other calls as well. So long story short: we have a test that mixes interacting with fake-gcs-server (only works with AnonymousCredentials) and generating presigned url (does not work with AnonymousCredentials).
Author
Owner

@ddelange commented on GitHub (Dec 23, 2022):

Apart from patching generate_presigned_url with a mock, is there another option you see?

<!-- gh-comment-id:1364277408 --> @ddelange commented on GitHub (Dec 23, 2022): Apart from patching `generate_presigned_url` with a mock, is there another option you see?
Author
Owner

@fsouza commented on GitHub (Dec 28, 2022):

Hey, I'm really sorry for the delay, things got a but busy at the end of the year with the holidays and me starting a new job.

Gotcha, I think this is also related to how the Python SDK was designed. For example, in the Go SDK, you're allowed to invoke a function to generate a signed URL, without ever creating a client instance, because that's technically not required.

So in terms of moving forward, the options are:

  1. mock generate_presigned_url like you mentioned
  2. change your production code to take different paths on generating signed URLs and using the GCS API (not great)
  3. adding that endpoint (and other auth-related endpoints) to fake-gcs-server

I'm OK with 3, as long as it's somewhat documented? And we can test it with a real SDK.

<!-- gh-comment-id:1366690110 --> @fsouza commented on GitHub (Dec 28, 2022): Hey, I'm really sorry for the delay, things got a but busy at the end of the year with the holidays and me starting a new job. Gotcha, I think this is also related to how the Python SDK was designed. For example, in the Go SDK, you're allowed to invoke a [function to generate a signed URL](https://pkg.go.dev/cloud.google.com/go/storage#SignedURL), without ever creating a client instance, because that's technically not required. So in terms of moving forward, the options are: 1. mock `generate_presigned_url` like you mentioned 2. change your production code to take different paths on generating signed URLs and using the GCS API (not great) 3. adding that endpoint (and other auth-related endpoints) to fake-gcs-server I'm OK with 3, as long as it's somewhat documented? And we can test it with a real SDK.
Author
Owner

@ddelange commented on GitHub (Dec 28, 2022):

Thanks for the reply. I've patched the call that talks to this endpoint under the hood. Communicating with fake-gcs-server in the tests now works properly, despite passing a fake service account (with real PEM) to the client instead of AnonymousCredentials.

Thanks again!

<!-- gh-comment-id:1366977654 --> @ddelange commented on GitHub (Dec 28, 2022): Thanks for the reply. I've [patched](https://github.com/stevearc/pypicloud/pull/320/commits/49ca312ffc88918528b3f5a0d37025b1da721c66) the call that talks to this endpoint under the hood. Communicating with fake-gcs-server in the tests now works properly, despite passing a fake service account (with real PEM) to the client instead of `AnonymousCredentials`. Thanks again!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/fake-gcs-server#151
No description provided.