Skip to content

Combining "Sign in with Google" with Casbin to add authentication and authorization to a Cloud Run service.

Notifications You must be signed in to change notification settings

gabihodoroaga/cloud-run-casbin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cloud-run-casbin

The is an example application of how you can use "Sign-in with Google" and Casbin to simplify identity and add authentication and authorization to a web application. You can read more in this blog post Simplified identity with 'Sign-in with Google' and Casbin

How to run locally

Setup database

Clone the repo:

git clone https://github.com/gabihodoroaga/cloud-run-casbin.git
cd cloud-run-casbin

Create the PostgreSQL server

docker run --name postgres -e POSTGRES_PASSWORD=password -d -p 5432:5432 postgres

Create the database

docker exec postgres psql -U postgres -c "CREATE DATABASE cloudrun_casbin;"

docker exec postgres psql -U postgres cloudrun_casbin \
    -c "CREATE TABLE IF NOT EXISTS users_roles ( \
    id SERIAL PRIMARY KEY, \
    email VARCHAR(100) NOT NULL, \
    role VARCHAR(100) NOT NULL, \
    CONSTRAINT ck_unique_role UNIQUE(email,role));"

Add the default admin user

docker exec postgres psql -U postgres -c "INSERT INTO users_roles (email, role) VALUES ('admin@example.com', 'admin');"

Run locally

POSTGRESQL_URL='user=postgres password=$POSTGRESQL_PASS database=cloudrun_casbin host=localhost' \
POSTGRESQL_PASS="password" \
GOOGLE_CLIENT_ID="[YOUR-GOOGLE-CLIENT-ID]" \
API_BASE_PATH="http://localhost:8080" \
go run .

In order to get a client id follow the instruction provide here: Get your Google API client ID

How to deploy on Cloud Run

Define variables:

PROJECT_ID=`gcloud config list --format 'value(core.project)' 2>/dev/null`
INSTANCE_NAME=casbin-test
REGION=us-central1
ZONE=us-central1-a
POSTGRESQL_PASS=SAflsakjw8j
GOOGLE_CLIENT_ID="[YOUR-GOOGLE-CLIENT-ID]"

Create SQL instance:

gcloud sql instances create $INSTANCE_NAME \
    --database-version=POSTGRES_13 \
    --tier=db-g1-small \
    --region=$REGION \
    --root-password=$POSTGRESQL_PASS

Run cloud_sql_proxy in another terminal (make sure to set the env variables correctly).

cloud_sql_proxy -instances=$PROJECT_ID:$REGION:$INSTANCE_NAME=tcp:5432

Create the database

PGPASSWORD=$POSTGRESQL_PASS psql -h localhost -p 5432 -U postgres -c "CREATE DATABASE cloudrun_casbin;"

Create the tables

PGPASSWORD=$POSTGRESQL_PASS psql -h localhost -p 5432 -U postgres cloudrun_casbin \
    -c "CREATE TABLE IF NOT EXISTS users_roles ( \
    id SERIAL PRIMARY KEY, \
    email VARCHAR(100) NOT NULL, \
    role VARCHAR(100) NOT NULL, \
    CONSTRAINT ck_unique_role UNIQUE(email,role));"

Add the default admin user

PGPASSWORD=$POSTGRESQL_PASS psql -h localhost -p 5432 -U postgres cloudrun_casbin \
    -c "INSERT INTO users_roles (email, role) VALUES ('admin@example.com', 'admin');"

Kill the cloud_sql_proxy process in the other terminal window.

Create a secret from the PostgreSQL password

echo -n "$POSTGRESQL_PASS" | gcloud secrets create postgres-password --data-file=-

Add permission for the default service account

PROJECT_NUMBER=$(gcloud projects list --filter=$PROJECT_ID --format="value(projectNumber)")
gcloud secrets add-iam-policy-binding postgres-password \
    --member=serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \
    --role='roles/secretmanager.secretAccessor'

Create the docker image for the web app

gcloud builds submit --tag gcr.io/$PROJECT_ID/webapp --project $PROJECT_ID .

Deploy to cloud run

gcloud run deploy webapp \
--image gcr.io/$PROJECT_ID/webapp \
--add-cloudsql-instances $PROJECT_ID:$REGION:$INSTANCE_NAME \
--set-env-vars=POSTGRESQL_URL="user=postgres password="'$POSTGRESQL_PASS'" database=cloudrun_casbin host=/cloudsql/$PROJECT_ID:$REGION:$INSTANCE_NAME"\
,GOOGLE_CLIENT_ID=$GOOGLE_CLIENT_ID \
--set-secrets POSTGRESQL_PASS=postgres-password:latest \
--allow-unauthenticated \
--project $PROJECT_ID \
--region $REGION

Get the url of the deployed service

SERVICE_URL=$(gcloud run services describe webapp --platform managed --region $REGION --format 'value(status.url)')

Update the API_BASE_PATH environment variable

gcloud run services update webapp \
    --region $REGION \
    --update-env-vars API_BASE_PATH=$SERVICE_URL

Update the "Authorized JavaScript origins" for the client id with the service url

echo $SERVICE_URL
# currently there is no option to update this using gcloud
# navigate to "APIs & Services"-> "Credentials" -> OAuth 2.0 Client IDs -> Edit 

TODO

[] Add unit tests

About

Combining "Sign in with Google" with Casbin to add authentication and authorization to a Cloud Run service.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published