May 8, 2020

Google App Engine Cloud Tasks and Django Rest Framework permissions

If you use Google App Engine, you can run tasks asynchronously using Cloud Tasks. It's simple. You can add a task to a queue with some payload which will be send to a specified API endpoint.

Related article: Google App Engine Standard, Python 3.7 and Cloud Tasks

It's essential to secure the API endpoint. It should be accessible only from the Cloud Tasks service. According to the documentation, you can verify the HTTP header.

All requests from Cloud Tasks Service contains X-Appengine-Queuename: true header. If someone tries to send a request with this header to the API, App Engine will remove it.

Using this information, you can create custom DRF permission.

from rest_framework import permissions
class IsTask(permissions.BasePermission):
def has_permission(self, request, view):
if request.META.get('HTTP_X_APPENGINE_QUEUENAME'):
return True
return False

Use permission_classes decorator to set the IsTask permission.

from rest_framework.decorators import api_view, permission_classes
from core.permissions.task import IsTask
@api_view(["GET"])
@permission_classes([IsTask])
def update_images(request):
# ...

Now we are sure that the API endpoint can only be used by the Cloud Tasks service.

© 2020 Przemysław Kołodziejczyk