# Google OAuth Verification — Boilerplates für Porta > Begleitdokument zu `google-oauth-setup.md`. Enthält copy-paste-fähige > Bausteine für die Google Trust-&-Safety-Verifizierung der **Porta**-App > (`porta.poweron.swiss`, Developer: `p.motsch@poweron.swiss`, > GCP-Projekt ``). ## App-Daten (zur konsistenten Wiederverwendung) | Feld | Wert | |----------------------------|-----------------------------------------------------------------------------------------------| | App-Name | Porta | | Anbieter (Legal Entity) | PowerOn AG | | Verifizierte Domain | `poweron.swiss` | | Homepage-URL | `https://porta.poweron.swiss/poweron-home.html` | | Privacy-Policy-URL | `https://porta.poweron.swiss/poweron-privacy.html` | | Terms-of-Service-URL | `https://porta.poweron.swiss/poweron-terms.html` | | Support-E-Mail | `support@poweron.swiss` | | Developer-Kontakt | `p.motsch@poweron.swiss` | | GCP-Projekt-Nummer | `` | | GCP-Projekt-ID | (siehe `env_prod.env`, `Service_GOOGLE_DATA_CLIENT_ID`) | | Verwendete Google-Scopes | `openid`, `userinfo.email`, `userinfo.profile`, `gmail.readonly`, `drive.readonly` | > Bei jeder Änderung an Scopes (`gateway/modules/auth/oauthProviderConfig.py::googleDataScopes`) > diese Tabelle, die OAuth-Consent-Screen-Konfiguration in der GCP-Console > **und** die Privacy-Policy synchron halten — Google bouncet sonst die > Verification. --- ## 1. Privacy-Policy-Sektion zu Google-Daten Die folgenden zwei Sektionen müssen **wortgleich** auf `https://porta.poweron.swiss/poweron-privacy.html` unter denselben Domain-/HTTPS-Bedingungen erreichbar sein wie die Homepage. Beide Sprachen anbieten (deutsche und englische Fassung), englische Fassung ist für Google maßgeblich. ### 1.1 Deutsche Fassung ```markdown ## Verarbeitung von Daten aus Google-Diensten Porta ist eine Plattform für KI-gestützte Geschäftsworkflows. Wenn Sie eine Verbindung zu Ihrem Google-Konto herstellen, greift Porta ausschließlich auf diejenigen Daten zu, die für die von Ihnen ausgewählte Funktionalität erforderlich sind, und ausschließlich mit den von Ihnen über den Google-OAuth- Consent-Bildschirm freigegebenen Berechtigungen (Scopes). ### Welche Google-Berechtigungen wir anfordern | Scope | Wozu Porta diese Berechtigung nutzt | |----------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------| | `openid`, `userinfo.email`, `userinfo.profile` | Anmeldung an Porta (Single-Sign-On) und eindeutige Zuordnung Ihres Benutzerkontos. | | `https://www.googleapis.com/auth/drive.readonly` | Lesezugriff auf Ihre Google-Drive-Dateien, damit Sie Dateien aus Drive im Porta-Workspace auswählen, vorschauen und der KI als Quelle übergeben können. Porta schreibt **nicht** in Ihr Drive. | | `https://www.googleapis.com/auth/gmail.readonly` | Lesezugriff auf Ihre Gmail-Labels und -Nachrichten, damit Sie E-Mails in Porta auflisten, vorschauen und einer KI-Konversation als Quelle anhängen können. Porta versendet, ändert oder löscht **keine** E-Mails. | ### Was mit den Daten geschieht * **Speicherung**: Porta speichert die OAuth-Refresh-Tokens verschlüsselt in der eigenen Datenbank, um ohne erneuten Login auf Ihre freigegebenen Daten zugreifen zu können. Inhalte aus Drive oder Gmail werden nur dann persistiert, wenn Sie sie aktiv als „Quelle" oder „Datei" in Porta anlegen; ansonsten werden sie nur transient für die jeweilige Anfrage geladen. * **Verwendung**: Drive- und Gmail-Daten werden ausschließlich genutzt, um Ihre direkten Anfragen in Porta zu beantworten (z.B. Dokument anzeigen, durchsuchen, einer KI-Konversation beifügen, automatisierte Workflows ausführen, die Sie selbst konfiguriert haben). * **Keine Weitergabe**: Porta gibt Daten aus Ihrem Google-Konto **nicht** an Dritte weiter, mit Ausnahme von Sub-Prozessoren, die für den Betrieb der Plattform notwendig sind (Cloud-Hosting, KI-Inferenz). Diese Sub-Prozessoren sind in Anhang A dieser Richtlinie aufgeführt und vertraglich auf den Schutz Ihrer Daten verpflichtet. * **Keine Werbung, kein Verkauf, kein Modelltraining**: Porta nutzt Daten aus Ihrem Google-Konto **nicht** für personalisierte Werbung, **nicht** für den Verkauf an Dritte und **nicht** für das Training generischer KI-Modelle. * **Menschlicher Zugriff**: Auf Ihre Google-Daten wird kein routinemäßiger menschlicher Zugriff genommen. Mitarbeiter der PowerOn AG können nur in den folgenden eng begrenzten Fällen Einsicht nehmen: (a) mit Ihrer ausdrücklichen Einwilligung, (b) zur Sicherheitsuntersuchung eines konkreten Vorfalls, (c) zur Erfüllung gesetzlicher Verpflichtungen, oder (d) wo dies zur Behebung eines technischen Fehlers in einer einzelnen Anfrage zwingend nötig ist. ### Limited Use Disclosure Porta hält die Anforderungen der **Google API Services User Data Policy** einschließlich der **Limited-Use-Anforderungen** ein. > *Porta's use and transfer of information received from Google APIs to any > other app will adhere to Google API Services User Data Policy, including the > Limited Use requirements.* > *()* ### Verbindung trennen und Daten löschen Sie können Ihre Google-Verbindung jederzeit beenden: 1. **In Porta**: Profil → Verbindungen → Google → „Trennen". Damit werden die bei Porta gespeicherten OAuth-Tokens unverzüglich widerrufen und gelöscht. 2. **In Ihrem Google-Konto**: → Porta auswählen → „Zugriff entfernen". Auf Anfrage an `support@poweron.swiss` löschen wir innerhalb von 30 Tagen sämtliche von Ihrem Google-Konto stammende Inhalte aus unseren Systemen (unbeschadet gesetzlicher Aufbewahrungspflichten). ``` ### 1.2 English version ```markdown ## Processing of Data from Google Services Porta is a platform for AI-assisted business workflows. When you connect your Google account, Porta accesses only the data that is required for the functionality you have selected, and only within the permissions (scopes) you have explicitly granted on the Google OAuth consent screen. ### Google permissions we request | Scope | How Porta uses this permission | |----------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------| | `openid`, `userinfo.email`, `userinfo.profile` | Sign-in to Porta (Single Sign-On) and unambiguous identification of your user account. | | `https://www.googleapis.com/auth/drive.readonly` | Read-only access to your Google Drive files, so that you can browse, preview and attach Drive files as sources to AI conversations and workflows in Porta. Porta does **not** write to your Drive. | | `https://www.googleapis.com/auth/gmail.readonly` | Read-only access to your Gmail labels and messages, so that you can list, preview and attach emails as sources to AI conversations in Porta. Porta does **not** send, modify or delete emails. | ### How we handle the data * **Storage**: Porta stores OAuth refresh tokens encrypted in its own database in order to access your authorized data without forcing you to re-authenticate. Content from Drive or Gmail is persisted only when you actively register it as a "source" or "file" in Porta; otherwise it is loaded transiently for the duration of the request only. * **Usage**: Drive and Gmail data are used exclusively to fulfill your direct requests within Porta (e.g., display, search, attach to an AI conversation, run an automated workflow you yourself have configured). * **No third-party sharing**: Porta does **not** share your Google data with third parties, except sub-processors strictly necessary to operate the platform (cloud hosting, AI inference). Sub-processors are listed in Annex A of this policy and are contractually bound to protect your data. * **No advertising, no sale, no model training**: Porta does **not** use your Google account data for personalized advertising, **not** for sale to third parties, and **not** to train generalized AI models. * **Human access**: Routine human access to your Google data does not occur. PowerOn AG personnel may access your Google data only in narrowly defined cases: (a) with your explicit consent, (b) for security investigation of a specific incident, (c) to comply with applicable law, or (d) where strictly necessary to fix a technical defect in a specific request. ### Limited Use Disclosure Porta complies with the requirements of the **Google API Services User Data Policy**, including the **Limited Use** requirements. > *Porta's use and transfer of information received from Google APIs to any > other app will adhere to the Google API Services User Data Policy, > including the Limited Use requirements.* > *()* ### Disconnecting and deleting your data You may revoke your Google connection at any time: 1. **In Porta**: Profile → Connections → Google → "Disconnect". This immediately revokes and deletes the OAuth tokens stored at Porta. 2. **In your Google account**: → select Porta → "Remove access". On request to `support@poweron.swiss`, we will delete all content originating from your Google account from our systems within 30 days (subject to statutory retention obligations). ``` --- ## 2. Justifications für jeden Scope (Verification-Formular) Google verlangt im Antrag pro Scope eine konkrete Begründung. **Wörtlich einkopierbar** in das Antragsformular: ### 2.1 `openid`, `userinfo.email`, `userinfo.profile` > Required to authenticate the user into Porta via Google Single Sign-On > and to identify their account uniquely. We display the user's email and > name within the application; we do not use these for any other purpose. ### 2.2 `https://www.googleapis.com/auth/drive.readonly` > Porta provides a unified data source panel where users can browse their > own Google Drive folders and attach selected Drive files (e.g., contracts, > reports, spreadsheets) as inputs to AI-driven conversations and to > automation workflows they configure themselves. We need read-only access > in order to (a) list folders and files the user owns or has shared access > to, (b) display file metadata such as name, type and modification date in > our source picker, and (c) download the file content on demand when the > user explicitly attaches a file to a chat or a workflow step. We do not > request write or full-Drive access; Porta never modifies or deletes the > user's Drive content. ### 2.3 `https://www.googleapis.com/auth/gmail.readonly` > Porta lets users attach individual Gmail messages as conversation > sources to its AI assistant (for example: "summarize this email", > "extract the invoice data from this thread") and use email content as > input to user-configured automation workflows. We need read-only access > in order to (a) list the user's labels in our source picker, (b) list > messages within a chosen label with metadata (subject, sender, date), and > (c) fetch a specific message body and attachments when the user > explicitly selects it. We do not request modify, send or full-mailbox > access; Porta never sends, alters or deletes the user's email. --- ## 3. Demo-Video — Drehbuch **Format**: YouTube unlisted, Bildschirmaufzeichnung mit Voice-Over (oder On-Screen-Text), Länge **2:30 – 4:00 min**, 1080p, Englisch (Google reviewt auf Englisch). Mauszeiger sichtbar, ruhiger Cursor. **Vor Aufnahme prüfen**: App in einem **frischen Inkognito-Fenster** öffnen, mit einem **echten Google-Account** (nicht „test@…"), in der URL-Leiste muss `porta.poweron.swiss` deutlich lesbar sein. ### Szene-für-Szene-Skript #### Szene 1 — Homepage & App-Identität (0:00 – 0:25) * **Bild**: Browser zeigt `https://porta.poweron.swiss`. Logo, App-Name „Porta", kurzer Marketing-Text sichtbar. * **Voice / On-Screen**: > *"This is Porta, available at porta.poweron.swiss. Porta is a > platform for AI-assisted business workflows. The OAuth client ID we are > submitting for verification belongs to this application."* #### Szene 2 — Sign-in starten (0:25 – 0:45) * **Bild**: User klickt „Sign in with Google". * **Voice / On-Screen**: > *"To use Porta, the user signs in with their Google account."* #### Szene 3 — OAuth-Consent-Screen (0:45 – 1:15) * **Bild**: Google-Consent-Bildschirm öffnet sich. **Klar lesbar**: App-Name „Porta", angeforderte Scopes (alle, einzeln aufgeführt), Privacy-Policy- und ToS-Link. * **Voice / On-Screen**: > *"Here Google shows the consent screen for Porta. The user can review > each requested permission individually: read access to Google Drive, > read access to Gmail, and basic profile information. The user grants > consent."* * User klickt „Continue" / „Allow". #### Szene 4 — Inside the app (1:15 – 1:30) * **Bild**: Nach erfolgreichem Login zeigt Porta das Workspace-Dashboard mit dem User-Namen oben rechts. * **Voice / On-Screen**: > *"After consent, the user is redirected back to Porta and is signed > in."* #### Szene 5 — Drive-Scope in action (1:30 – 2:15) * **Bild**: 1. User öffnet die UDB („Unified Data Bar") → Tab „Sources". 2. Wählt die Google-Connection. 3. Klickt auf „Drive". Die Liste der Drive-Ordner und -Dateien erscheint. 4. User wählt eine Datei (z.B. ein PDF) und klickt „Attach to chat". 5. Im Chat-Eingabefeld erscheint die Datei als Anhang-Chip. User tippt "Summarize this document" und sendet. 6. Die KI-Antwort referenziert den Inhalt der Datei. * **Voice / On-Screen**: > *"Porta uses the Drive read-only scope to let the user browse their > Drive, attach a specific file as a source for the AI conversation, and > then have the AI process exactly that file. Porta does not modify or > delete anything in the user's Drive."* #### Szene 6 — Gmail-Scope in action (2:15 – 3:00) * **Bild**: 1. Zurück in „Sources" → Google-Connection → Klick auf „Gmail". 2. Die Liste der Gmail-Labels („INBOX", „SENT", eigene Labels) erscheint. 3. User öffnet ein Label, eine Liste von Mails (Subject, From, Date) wird angezeigt. 4. User wählt eine Mail und klickt „Attach to chat". 5. Im Chat erscheint die Mail als Quelle. User tippt z.B. „Extract the order details from this email" und sendet. 6. Die KI-Antwort zeigt strukturierte Felder aus der Mail. * **Voice / On-Screen**: > *"The Gmail read-only scope is used so the user can pick a specific > email to feed into an AI conversation. Porta lists labels and > messages and fetches the body only of the message the user explicitly > selects. Porta never sends, modifies or deletes email."* #### Szene 7 — Disconnect (3:00 – 3:30) * **Bild**: User öffnet Profil → Connections → Google-Eintrag → klickt „Disconnect". Bestätigungsdialog. Der Eintrag verschwindet. * **Voice / On-Screen**: > *"At any time, the user can disconnect their Google account in > Porta. This immediately revokes and deletes the stored OAuth > tokens."* #### Szene 8 — Privacy Policy (3:30 – 3:50) * **Bild**: Browser navigiert zu `https://porta.poweron.swiss/poweron-privacy.html`. Scrollen zur Sektion „Processing of Data from Google Services" und zur „Limited Use Disclosure". * **Voice / On-Screen**: > *"Our privacy policy at porta.poweron.swiss/poweron-privacy.html explicitly lists > each Google scope, the purpose of each scope, and includes the Limited > Use Disclosure as required by the Google API Services User Data Policy."* #### Szene 9 — Outro (3:50 – 4:00) * **Bild**: Porta-Logo, App-Name, Submission-Datum. * **Voice / On-Screen**: > *"Thank you for reviewing Porta for OAuth verification."* ### Aufnahme-Checkliste * [ ] URL-Bar in jedem Frame zeigt `porta.poweron.swiss` (kein localhost, kein staging). * [ ] Browser-Inkognito, keine Browser-Extensions sichtbar. * [ ] Consent-Screen zeigt korrekten App-Namen „Porta" und korrektes Logo. * [ ] Jeder im Antrag deklarierte Scope ist in mindestens einer Szene *aktiv genutzt* zu sehen (nicht nur erwähnt). * [ ] Kein „Lorem-ipsum", keine Demo-Daten mit „test", „dummy", „foo". * [ ] Audio sauber oder Sprache als On-Screen-Text eingeblendet. * [ ] Video als **unlisted** auf YouTube hochladen, Link ins Verification-Formular eintragen. --- ## 4. Pre-Submission-Checkliste Vor dem (erneuten) Klick auf „Submit for verification" alles abhaken: * [ ] Domain `poweron.swiss` in der **Google Search Console** verifiziert (DNS-TXT, gleicher Google-Account wie OAuth-Owner). * [ ] `https://porta.poweron.swiss` öffentlich erreichbar, HTTPS, kein Login-Wall, beschreibt klar was Porta ist. * [ ] `https://porta.poweron.swiss/poweron-privacy.html` öffentlich erreichbar, enthält die beiden Sektionen aus Kapitel 1 dieses Dokuments. * [ ] `https://porta.poweron.swiss/poweron-terms.html` öffentlich erreichbar. * [ ] OAuth-Consent-Screen in der GCP-Console: * App-Name „Porta", App-Logo (120×120 PNG, kein Google-Branding). * Support-E-Mail `support@poweron.swiss`. * Authorized domain: `poweron.swiss`. * Application home page: `https://porta.poweron.swiss`. * Application privacy policy link: `https://porta.poweron.swiss/poweron-privacy.html`. * Application terms of service link: `https://porta.poweron.swiss/poweron-terms.html`. * [ ] Scope-Liste im Consent-Screen identisch zu `googleDataScopes` in `gateway/modules/auth/oauthProviderConfig.py`. * [ ] Jeder Scope hat eine Justification (Kapitel 2 dieses Dokuments). * [ ] Demo-Video (Kapitel 3) auf YouTube unlisted, Link im Antrag. * [ ] Developer-E-Mail `p.motsch@poweron.swiss` empfangsbereit; Eingangs-Mail vom Trust-&-Safety-Team kommt erfahrungsgemäß innerhalb 3-5 Tagen. --- ## 5. Was tun, wenn Google rejected Erfahrungsgemäß werden mindestens 1-2 Iterationen bis zur Approval nötig. Häufigste Reject-Gründe und Fixes: | Reject-Grund | Fix | |--------------------------------------------------------|------------------------------------------------------------------------------------------------------| | „Privacy policy does not enumerate all requested scopes" | Sektion 1.2 dieses Dokuments wörtlich übernehmen, jeden Scope aus Tabelle erwähnen. | | „Demo video does not show scope X being used" | Eine zusätzliche Szene im Video, in der Scope X aktiv ausgeübt wird (siehe Szene 5/6). | | „Homepage does not describe what the app does" | Auf `porta.poweron.swiss` einen klaren „What is Porta"-Block oberhalb des Login-Buttons. | | „Brand verification — domain not verified" | Domain in Google Search Console verifizieren mit demselben Account wie OAuth-Owner. | | „Limited Use disclosure missing" | Wörtliche Limited-Use-Klausel aus Sektion 1.2 in die Privacy-Policy aufnehmen. | | „App requests scopes broader than necessary" | Prüfen ob `gmail.readonly` durch `gmail.metadata` ersetzt werden kann (nicht für Porta — wir lesen Inhalte). Begründen. | Bei jedem Re-Submit nur die beanstandeten Punkte fixen, kein „While we're at it" — das verlängert den Loop. --- ## 6. Wenn Verification durch ist * GCP-Console → OAuth Consent Screen → Publishing Status „**In Production**". * Test-Users-Liste kann geleert werden (nicht nötig zu entfernen, schadet aber auch nicht). * Externe User sehen ab sofort keinen Warn-Bildschirm mehr, nur den normalen, signierten Consent-Screen mit App-Logo. * Bei jeder zukünftigen Scope-Änderung in `googleDataScopes`: erneut durch Verification, **mit derselben Vorgehensweise**. Daher Scopes bewusst minimal halten.