View on GitHub

core

Cloud Robotics Core: Kubernetes, Federation, App Management

Debugging authentication problems

Useful tips for working with Authentication and Authorization systems.

Run a sample request with various credentials

You can call Cloud APIs with curl to see whether authorization works.

Your own credentials

PROJECT_NUMBER=201199916163
curl -v -H "Content-Type: application/json" \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        "https://cloudroboticssensordata.googleapis.com/v1eap/projects/${PROJECT_NUMBER}/sensors"

Service account JSON file

You can create a JSON file with the robot account’s credentials on the Cloud console’s credentials page.

PROJECT_NUMBER=201199916163
JSON_CREDENTIALS=/tmp/my-project-b7364a68fa92.json
curl -v -H "Content-Type: application/json" \
        -H "Authorization: Bearer $(GOOGLE_APPLICATION_CREDENTIALS=${JSON_CREDENTIALS) gcloud auth application-default print-access-token)" \
        "https://cloudroboticssensordata.googleapis.com/v1eap/projects/${PROJECT_NUMBER}/sensors"

Get an OAuth token from IAM

The token vendor doesn’t have its own keys, but instead calls IAM’s generateAccessToken method. You can emulate its behavior by using the API Explorer to call iamcredentials.projects.serviceAccounts.generateAccessToken. The name parameter is projects/-/serviceAccounts/robot-service@my-project.iam.gserviceaccount.com, and the scope is https://www.googleapis.com/auth/cloud-platform.

You can pass the returned access token in an Authorization header as above.

Check whether the client’s request is well-formed and authenticated

The easiest way to verify that metadata server and the gRPC client library are doing the right thing is to use a logging HTTP server as the gRPC server. Instead of setting the gRPC host to the Cloud API server (cloudroboticssensordata.googleapis.com), you set it to an HTTPS-capable server under your control. You need HTTPS support because otherwise the gRPC library will rightfully decline to send access tokens.

Luckily, your Cloud Robotics Core setup already runs an HTTPS server. Suppose you’re calling the gRPC service google.cloud.robotics.sensordata.v1eap.SensorDataService. You can hook a very simple Python HTTP server into your cloud nginx setup like this:

apiVersion: v1
kind: ConfigMap
metadata:
  name: debug
spec:
  server.py: |
    import BaseHTTPServer
    import SocketServer

    class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):

      def do_GET(self):
        print "Got request for ", self.path, " with auth ", self.headers.get('Authorization')

      def do_POST(self):
        print "Got request for ", self.path, " with auth ", self.headers.get('Authorization')

    httpd = SocketServer.TCPServer(("", 8080), MyHandler)
    httpd.serve_forever()
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: debug
spec:
  selector:
    matchLabels:
      app: debug
  replicas: 1
  template:
    metadata:
      labels:
        app: debug
    spec:
      containers:
      - name: python
        image: python:2
        args: ["python", "/src/server.py"]
        volumeMounts:
        - name: src-volume
          mountPath: /src
      volumes:
      - name: src-volume
        configMap:
          name: debug
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: debug
  name: debug
spec:
  ports:
  - name: http
    port: 8082
    protocol: TCP
    targetPort: 8080
  selector:
    app: debug
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: HTTP
  name: debug
spec:
  ingressClassName: nginx
  rules:
  - host: www.endpoints.my-project.cloud.goog
    http:
      paths:
      - path: /google.cloud.robotics.sensordata.v1eap.SensorDataService
        pathType: Prefix
        backend:
          service:
            name: debug
            port
              number: 8080

This will log the Authorization header to the pod’s stdout, so you can view it with kubectl logs. Save the token to a file (don’t paste it into the command line because it will end up in your shell history).

Checking tokens with the tokeninfo service

You can check the token’s contents and sanity with Google’s tokeninfo endpoint:

curl https://oauth2.googleapis.com/tokeninfo?access_token=$(cat /tmp/token.txt)