decaporg / decap-cms

A Git-based CMS for Static Site Generators
https://decapcms.org
MIT License
17.67k stars 3.03k forks source link

AWS Cognito Proxy for Github #7014

Closed soceanainn closed 5 months ago

soceanainn commented 6 months ago

Summary

Github / Netlify seats are expensive. Creating an authenticated proxy of the Github API using AWS Cognito is very cost effective (if less performant due to nature of proxying).

This was solved by introducing a new aws-cognito-github-proxy backend that shims the github backend. The authentication page is generic and uses the existing PKCE authenticator for AWS Cognito login.

Some actions will not be available to the proxied bot user (e.g. forking repos). Avatar URL for logged in user defaults to the repo owner avatar in Github.

The changes required in existing packages to achieve this goal were as follows:

  1. Update PKCE authenticator to accept auth_token_endpoint_content_type as input (AWS Cognito requires application/x-www-form-urlencoded, existing implementations for gitea / gitlab use application/json). Also make redirect_uri configurable.
  2. Update Github API to make 'tokenKeyword' configurable. Github uses token for JWTs (and sometimes allows use of Bearer), AWS Cognito uses Bearer at all times.
  3. Allow bypassing 'writeAccess' check for proxy. This is because Github App tokens are different from class user / Oauth app tokens in Github, and will never have explicit push permissions for the repository.
  4. Centralize getUser()/currentUser()/user() calls (fetching user information from Github or alternate sources) and make that configurable (so we can pass from 'backend' implementation into 'API' implementation and override for Git Gateway / Cognito proxy).
  5. Allow passing base_url (authorization base URL) around in Github backend + API, so we can use this to fetch info from AWS Cognito for aws-cognito-github-proxy. Existing docs / code sometimes put this field in backend configuration, sometimes it's a top level line item. I went with documented location (backend config) instead of where it was specified in typescript (meaning it's now present in two locations there).
  6. Export GitHubUser type so we can cast custom object to it. This seems like the wrong type to be using across Github backend/API - the User interface is probably better but that is a large refactoring than I wanted to do with feature changes.

Test plan

I built this using yarn run build then copied it into my private repo. I tested the full log-in flow and the editorial workflow for simple changes to some pages.

Specific backend configuration for this new backend (ignoring shared Github options) is something like:

  name: aws-cognito-github-proxy
  base_url: https://cognito.example.com
  app_id: {{ COGNITO CLIENT ID }}
  api_root: {{ GITHUB API PROXY URL }}

Detailed examples of the proxy I created to run this, and on setting this up using AWS Cloudformation are visible in this repo: https://github.com/gael-cms/aws-cognito-github-proxy

Checklist

Please add a x inside each checkbox:

netlify[bot] commented 6 months ago

Deploy request for cms-demo rejected.

Name Link
Latest commit e978f0e5231420b3dd7d176c06ec25a959700973
netlify[bot] commented 6 months ago

Deploy Preview for decap-www canceled.

Name Link
Latest commit 4a3b90c540435161561b5b3fcfd1b6ffd1cfdbd2
Latest deploy log https://app.netlify.com/sites/decap-www/deploys/65b8f796b199c20008d19084
demshy commented 6 months ago

@seamuswn you mind getting this up to date with the latest master? I'm ready to merge this and then release the new beta version

soceanainn commented 6 months ago

@demshy apologies for the delay - stuff was a bit hectic here before the winter break.

I just rebased and I'm testing everything E2E again to make sure it's all working. I'll let you know when I'm finished testing again.

soceanainn commented 6 months ago

Looks good on my side after rebasing, rebuilding and running locally!

demshy commented 5 months ago

Hey @soceanainn I'm sorry but stuff has now been hectic on our side as well but I finally got some time that I can put into the project. I noticed that the tests failed due to a lint error. Would you mind formatting the code and rebasing the latest master again?

demshy commented 5 months ago

this is great, all we need is another master update and it's done :)