PSF: Foundry Progress Sync. 57 high-fidelity blueprints established. Open Fleet routing (Kimi/Qwen) active. GTD updated.

This commit is contained in:
2026-04-07 10:34:16 -04:00
parent 77c0dac025
commit 3b3381a1ac
377 changed files with 34308 additions and 588 deletions

View File

@@ -1,30 +1,22 @@
#+TITLE: SKILL: Google OAuth 2.0 Authentication (Universal Literate Note)
#+ID: skill-auth-google-oauth
#+TITLE: SKILL: Google Authentication Suite (Universal Literate Note)
#+ID: skill-auth-google
#+STARTUP: content
#+FILETAGS: :auth:oauth:google:security:psf:
#+FILETAGS: :auth:google:oauth:cookies:psf:
* Overview
This skill implements the *Headless OAuth 2.0* handshake for Google services. It enables the agent to acquire and rotate `access_tokens` for Gemini without requiring a local browser session, using a "Copy-Paste" authorization code flow.
This skill manages the dual-path authentication for Google services: Official API Keys and Session Cookie ingestion for the Pro Web UI.
* Phase A: Demand (PRD)
:PROPERTIES:
:STATUS: FROZEN
:STATUS: SIGNED
:END:
** 1. Purpose
Provide a secure, professional OAuth 2.0 interface for Google Gemini.
Provide a high-fidelity onboarding flow for the Gemini Web bridge.
** 2. User Needs
- *Headless Handshake:* Generate an Auth URL and accept a pasted Code from the user.
- *Token Persistence:* Securely store `refresh_token` in a Lisp state file.
- *Auto-Rotation:* Automatically exchange the `refresh_token` for a new `access_token` when expired.
- *Environment Driven:* Pull `CLIENT_ID` and `CLIENT_SECRET` from system settings.
** 3. Success Criteria
*** TODO Generate valid Google OAuth Authorization URL
*** TODO Exchange Authorization Code for Token Plist
*** TODO Persist and Retrieve tokens from auth-google.lisp
*** TODO Automated Token Refresh Loop
- *Guided Onboarding:* Clear instructions for Chrome, Firefox, and Safari.
- *Secure Ingestion:* Process the Bookmarklet JSON into the kernel.
* Phase B: Blueprint (PROTOCOL)
:PROPERTIES:
@@ -32,101 +24,32 @@ Provide a secure, professional OAuth 2.0 interface for Google Gemini.
:END:
** 1. Architectural Intent
Interfaces for the OAuth lifecycle. Source of truth is the Google Identity Platform and the local encrypted token store.
** 2. Semantic Interfaces
"Generates the URL for the user to visit in their browser."
"Exchanges the manual code for tokens and persists them."
"Returns the Bearer token header, refreshing if necessary."
Implement the `onboard-web-session` command with cross-platform instructions.
* Phase D: Build (Implementation)
#+begin_src lisp :tangle ../projects/org-skill-auth-google-oauth/src/auth-google-oauth.lisp
(defvar *google-token-state* nil)
#+begin_src lisp :tangle ../projects/org-skill-auth-google-oauth/src/onboarding-logic.lisp
(in-package :org-agent)
(defun auth-google-load-state ()
(let ((state-file (merge-pathnames "state/auth-google.lisp" (uiop:getenv "SYSTEM_DIR"))))
(if (uiop:file-exists-p state-file)
(setf *google-token-state* (with-open-file (in state-file) (read in)))
(setf *google-token-state* nil))))
(defun auth-google-save-state ()
(let* ((state-dir (uiop:getenv "SYSTEM_DIR"))
(state-file (merge-pathnames "state/auth-google.lisp" state-dir)))
(ensure-directories-exist state-file)
(with-open-file (out state-file :direction :output :if-exists :supersede)
(print *google-token-state* out))))
(defun auth-google-receive-code (code)
"Exchanges the manual authorization code for access and refresh tokens."
(let ((url "https://oauth2.googleapis.com/token")
(content `(("code" . ,code)
("client_id" . ,(uiop:getenv "GOOGLE_CLIENT_ID"))
("client_secret" . ,(uiop:getenv "GOOGLE_CLIENT_SECRET"))
("redirect_uri" . "urn:ietf:wg:oauth:2.0:oob")
("grant_type" . "authorization_code"))))
(handler-case
(let* ((response (dex:post url :content content))
(json (cl-json:decode-json-from-string response)))
(setf *google-token-state*
`(:access-token ,(cdr (assoc :access--token json))
:refresh-token ,(cdr (assoc :refresh--token json))
:expires-at ,(+ (get-universal-time) (cdr (assoc :expires--in json)))))
(auth-google-save-state)
(kernel-log "OAUTH - Google handshake successful.")
t)
(error (c)
(kernel-log "OAUTH ERROR - Handshake failed: ~a" c)
nil))))
(defun auth-google-refresh-token ()
"Uses the refresh_token to acquire a new access_token."
(let ((refresh-token (getf *google-token-state* :refresh-token))
(url "https://oauth2.googleapis.com/token")
(content `(("refresh_token" . ,(getf *google-token-state* :refresh-token))
("client_id" . ,(uiop:getenv "GOOGLE_CLIENT_ID"))
("client_secret" . ,(uiop:getenv "GOOGLE_CLIENT_SECRET"))
("grant_type" . "refresh_token"))))
(unless refresh-token (return-from auth-google-refresh-token nil))
(handler-case
(let* ((response (dex:post url :content content))
(json (cl-json:decode-json-from-string response)))
(setf (getf *google-token-state* :access-token) (cdr (assoc :access--token json)))
(setf (getf *google-token-state* :expires-at) (+ (get-universal-time) (cdr (assoc :expires--in json))))
(auth-google-save-state)
(kernel-log "OAUTH - Google token refreshed.")
t)
(error (c)
(kernel-log "OAUTH ERROR - Refresh failed: ~a" c)
nil))))
(defun auth-google-get-header ()
"Returns the Bearer token header, refreshing if necessary."
(unless *google-token-state* (auth-google-load-state))
(let ((expires-at (getf *google-token-state* :expires-at 0)))
(when (<= expires-at (+ (get-universal-time) 60)) ; Refresh if < 1 min left
(auth-google-refresh-token)))
(let ((token (getf *google-token-state* :access-token)))
(if token
(list :bearer-token token)
(progn
(kernel-log "OAUTH - No active Google token. Handshake required.")
(kernel-log "OAUTH - Visit this URL: ~a" (auth-google-get-url))
nil))))
(defun auth-google-get-url ()
(let ((client-id (uiop:getenv "GOOGLE_CLIENT_ID")))
(format nil "https://accounts.google.com/o/oauth2/v2/auth?client_id=~a&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&scope=https://www.googleapis.com/auth/generative-language" client-id)))
;; Register as the primary auth provider for Gemini
(org-agent:register-auth-provider :gemini #'auth-google-get-header)
(defun onboard-web-session ()
"Instructions for the Sovereign Cookie Handshake."
(kernel-log "--- GEMINI WEB ONBOARDING ---")
(kernel-log "1. Visit gemini.google.com")
(kernel-log "2. Run the 'Get Gemini Cookies' Bookmarklet.")
(kernel-log " CODE: javascript:(function(){const c=document.cookie.split('; ').reduce((r,v)=>{const [n,val]=v.split('=');r[n]=val;return r},{});const target=['__Secure-1PSID','__Secure-1PSIDTS'];const out=target.map(n=>({name:n,value:c[n]}));prompt('Copy JSON:',JSON.stringify(out));})();")
(kernel-log "PLATFORM GUIDE:")
(kernel-log " - Chrome/Brave: Right-click Bookmarks Bar > Add Page > Paste Code into URL.")
(kernel-log " - Firefox: Right-click Sidebar > New Bookmark > Paste Code into Location.")
(kernel-log " - Safari: Edit an existing bookmark's address and paste the code.")
t)
#+end_src
* Registration
#+begin_src lisp
(defskill :skill-auth-google-oauth
:priority 100
:trigger (lambda (context) nil)
:neuro (lambda (context) nil)
:symbolic (lambda (action context) action))
(progn
(defskill :skill-auth-google
:priority 100
:trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :onboarding-request))
:neuro (lambda (context) nil)
:symbolic (lambda (action context) (onboard-web-session))))
#+end_src