Get YouTube posting credentials¶
Set up a Google Cloud OAuth app so keryx auth youtube can capture a refresh
token and keryx post youtube can upload a reel as a Short. This mirrors
the Instagram credentials guide; the difference is
Google's OAuth (a durable refresh token + 1-hour access tokens) and a longer
approval path for public uploads.
Status: app-registration steps (§1–§5) are ready to follow now — this is the long-lead item, so start it early. The
keryx auth youtube/ posting sections (§6+) are filled in as the adapter lands (spec0007-youtube.md).
What you need¶
- A Google account that owns a YouTube channel (the channel you'll post to).
- ~20 minutes for the Cloud Console setup; the verification/audit for public posting is separate and takes weeks (see §5) — uploads stay private until it's done, which is fine for building and testing.
1. Create a Google Cloud project¶
- Go to the Google Cloud Console → https://console.cloud.google.com/.
- Project picker (top bar) → New Project. Name it e.g.
keryx. Create, then select it.
2. Enable the YouTube Data API v3¶
- APIs & Services → Library (
https://console.cloud.google.com/apis/library). - Search "YouTube Data API v3" → open it → Enable.
3. Configure the OAuth consent screen¶
APIs & Services → OAuth consent screen
(https://console.cloud.google.com/apis/credentials/consent):
- User type: External (choose Internal only if this is a Google Workspace org and the channel is inside it). Create.
- App information: app name (
keryx), your user support email, and a developer contact email. - Scopes → Add or remove scopes → manually add:
https://www.googleapis.com/auth/youtube.uploadThis is a restricted scope (it's what triggers the verification/CASA requirement for public use in §5). Save. - Test users → Add users: add the Google account that owns the channel. While the app is in Testing, only listed test users can authorise it.
- Save.
4. Create the OAuth client (Desktop app)¶
APIs & Services → Credentials
(https://console.cloud.google.com/apis/credentials):
- Create credentials → OAuth client ID.
- Application type: Desktop app. Name it (
keryx-cli). Create. - Copy the Client ID and Client secret. These are what keryx needs:
platforms.youtube.client_id(non-secret) — goes in keryx config.YOUTUBE_CLIENT_SECRET(secret) — env var / keychain, never committed.
Desktop-app clients use the loopback redirect (
http://127.0.0.1:<port>) that keryx already serves — no redirect URL to register (Google allows any loopback port, RFC 8252). Nothing to paste into the console here.
5. Publishing status & the audit (the long pole)¶
On the OAuth consent screen, the app starts in Testing:
- Testing: usable immediately by your test users, but refresh tokens expire after 7 days — fine for a first end-to-end test, not for unattended use.
- Publish App → "In production": refresh tokens become durable (no 7-day expiry). You can publish even while unverified; you (the owner/test user) click past the "Google hasn't verified this app" screen. Do this to get a lasting refresh token.
- Public uploads (so videos aren't forced to
privateand quota isn't capped) additionally require app verification + the YouTube API Audit & Quota Extension + a CASA security assessment. This is the weeks-long part. Until it's granted, keryx keepsplatforms.youtube.privacy: private.
For now: enable the API (§2), set up consent (§3), create the Desktop client (§4), and Publish to "In production" (§5) so the refresh token persists. Defer the full audit until the implementation is confirmed working on private uploads. Start the Audit & Quota Extension when you're ready to go public.
Official references¶
- YouTube Data API v3 — Uploads and videos.insert guides.
- Google Identity — Using OAuth 2.0 for Installed/Desktop Applications and Loopback IP address flow.
- Google API Services — OAuth verification, Restricted scopes, and the YouTube API Services Audit (incl. CASA).
6. Authorise keryx¶
With the client id in config (platforms.youtube.client_id), the secret in the
environment (YOUTUBE_CLIENT_SECRET), and the app published to production:
It prints (and tries to open) a Google authorize URL and runs a plain-http
loopback callback on a free port — no cert, no warning. Approve the YouTube
permission (click past the one-time "Google hasn't verified this app" →
Advanced → Go to keryx), and it captures the code, exchanges it for a
refresh token, and stores it (keychain on a desktop, else the config file).
platforms.youtube.enabled flips true.
- Remote/headless box: the redirect targets
127.0.0.1:<port>on your machine, so reach the host the same way as the Instagram flow — an SSH port-forward, or change the address-bar host to the box's LAN IP. Pin a fixed port with--redirect http://127.0.0.1:<port>/if you need to forward it. - Scope note: keryx requests only
youtube.upload, which can't readchannels.list, so the channel id is recorded best-effort — it isn't needed to upload (videos.inserttargets the authorised channel).
Once authorised, keryx post youtube uploads a rendered reel as a private
Short (until the audit lifts the cap). The capture flow reuses
keryx auth.