1

I have an HTML-triggered Cloud Function which has permissions set to allUsers:

function

When I access the function at the trigger address, it correctly returns an HTML page but gives a Forbidden error on the associated stylesheet:

html

error

I don't see any documentation about how to configure permissions on individual folders within a cloud function. The Flask server used by the Python runtime puts all static resources in /static rather than individual css, img, and js folders - I haven't tried configuring Flask to somewhere else because there's no non-magical reason for the default location to fail.

Note: App Engine has an app.yaml configuration file (https://cloud.google.com/appengine/docs/standard/python3/serving-static-files), but I don't see any equivalent for Cloud Functions.

Any clue how to avoid permission errors in Google's implementation of Flask?

7
  • Google Cloud IAM does not provide features for managing URLs (directories and files) within Cloud Functions. IAM provides authorization to the service and not to your application internals. Jan 10, 2020 at 0:14
  • Thanks @JohnHanley, that's what I assumed. Which is why it's bizarre that IAM permissions for Cloud Functions allows access to the HTML but CSS gets a Forbidden. Why that happens and how to fix it is the question.
    – Dave
    Jan 10, 2020 at 15:17
  • Cloud Functions is not a web server. Cloud Functions has an entry point (endpoint) that you call that invokes a function. You cannot have multiple URLs for a single function. Look at App Engine or Cloud Run if you are trying to provide web services. Jan 10, 2020 at 15:36
  • I'm not sure where you get that idea. The very first Hello World for Cloud Functions is a web server, and it can support as many URL paths as you want - cloud.google.com/functions/docs/first-python.
    – Dave
    Jan 10, 2020 at 17:28
  • RTM: cloud.google.com/functions/docs/concepts/exec: "Cloud Functions implements the serverless paradigm, in which you just run your code without worrying about the underlying infrastructure, such as servers or virtual machines. To allow Google to automatically manage and scale the functions, they must be stateless—one function invocation should not rely on in-memory state set by a previous invocation." I have servers running on App Engine now, but for stateless web services CF is appropriate.
    – Dave
    Jan 10, 2020 at 17:37

1 Answer 1

1

The permission errors are caused by an anomaly in the Cloud Functions Python runtime - the cloud function name is missing from URLs. A page accessed at the HTML trigger

http://<region-project>.cloudfunctions.net/function-1/home

containing a link

/static/style.css

appears to have a document root at ...cloudfunctions.net/, not ...cloudfunctions.net/function1/.

Python request.url is ...cloudfunctions.net/home, not the correct ...cloudfunctions.net/function-1/home when request.path is /home if the code is running on Cloud Functions.

A workaround is to manually patch all URLs referring to the cloud function to prepend the FUNCTION_NAME environment variable when the page is rendered from a template:

def getenv(name, default):
    try:
        return os.environ[name]
    except KeyError:
        return default

def _url(request, path):       # Patch URLs to include FUNCTION_NAME if running on GCP
    f = getenv('FUNCTION_NAME', '')
    return request.url + (f + '/' if f else '') + path

This results in a page that will display correctly from Cloud Functions without causing permission errors:

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.