# Deploying Permit PDP on GCP Cloud Run

## Prerequisites

- Google Cloud SDK installed and configured
- A GCP project with billing enabled
- A Permit.io API key

## Step 1: Enable Required APIs

```bash
gcloud services enable secretmanager.googleapis.com
gcloud services enable run.googleapis.com
```

## Step 2: Create a Secret for the API Key

Store your Permit API key securely in GCP Secret Manager:

```bash
echo -n "YOUR_PERMIT_API_KEY" | gcloud secrets create permit-pdp-api-key \
  --data-file=- \
  --replication-policy=automatic
```

## Step 3: Grant Secret Access to the Service Account

Get your default compute service account and grant it access to the secret:

```bash
# Get the service account email
SERVICE_ACCOUNT=$(gcloud iam service-accounts list --format="value(email)" | grep compute)

# Grant secret access
gcloud secrets add-iam-policy-binding permit-pdp-api-key \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/secretmanager.secretAccessor"
```

## Step 4: Create the Cloud Run Service YAML

Create a file named `permit-pdp-service.yaml`:

```yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: permit-pdp
  labels:
    cloud.googleapis.com/location: us-central1
  annotations:
    run.googleapis.com/client-name: cloud-console
    run.googleapis.com/ingress: all
    run.googleapis.com/ingress-status: all
spec:
  template:
    metadata:
      labels:
        run.googleapis.com/startupProbeType: Default
      annotations:
        run.googleapis.com/cpu-throttling: "false"
        run.googleapis.com/client-name: cloud-console
        autoscaling.knative.dev/minScale: "1"
        autoscaling.knative.dev/maxScale: "10"
    spec:
      containerConcurrency: 80
      timeoutSeconds: 300
      serviceAccountName: YOUR_SERVICE_ACCOUNT_EMAIL
      containers:
        - image: permitio/pdp-v2:latest
          ports:
            - name: http1
              containerPort: 7000
          env:
            - name: PDP_API_KEY
              valueFrom:
                secretKeyRef:
                  key: latest
                  name: permit-pdp-api-key
          resources:
            limits:
              cpu: 1000m
              memory: 512Mi
          startupProbe:
            timeoutSeconds: 240
            periodSeconds: 240
            failureThreshold: 1
            tcpSocket:
              port: 7000
  traffic:
    - percent: 100
      latestRevision: true
```

**Important Configuration Notes:**

| Setting | Value | Purpose |
|---------|-------|---------|
| `run.googleapis.com/cpu-throttling` | `"false"` | Prevents SIGABRT errors by keeping CPU allocated |
| `autoscaling.knative.dev/minScale` | `"1"` | Avoids cold starts that cause authorization failures |
| `containerPort` | `7000` | Default PDP port |
| `startupProbe.timeoutSeconds` | `240` | Allows time for initial policy sync |

## Step 5: Deploy the Service

```bash
gcloud run services replace permit-pdp-service.yaml --region=us-central1
```

## Step 6: Allow Public Access (Optional)

If you need unauthenticated access to the PDP:

```bash
gcloud run services add-iam-policy-binding permit-pdp \
  --region=us-central1 \
  --member="allUsers" \
  --role="roles/run.invoker"
```

## Step 7: Verify the Deployment

Check the health endpoint:

```bash
# Get the service URL
SERVICE_URL=$(gcloud run services describe permit-pdp --region=us-central1 --format="value(status.url)")

# Check health
curl ${SERVICE_URL}/health
```

Expected response:
```json
{"components":{"horizon":{"details":{"direct_check":"success","watchdog":"error"},"error":null,"status":"ok"},"opa":{"error":null,"status":"ok"}},"status":"ok"}
```

## Endpoints

Once deployed, your PDP exposes:

- **Health Check**: `https://YOUR_SERVICE_URL/health`
- **Authorization**: `https://YOUR_SERVICE_URL/allowed`

## Troubleshooting

### Signal 6 (SIGABRT) Errors
Ensure `run.googleapis.com/cpu-throttling: "false"` is set in your annotations.

### Cold Start Authorization Failures
Ensure `autoscaling.knative.dev/minScale: "1"` to keep at least one instance running.

### Quota Errors
Reduce `autoscaling.knative.dev/maxScale` if you hit CPU/memory quota limits.
