Inspiration
Social posting for a brand often lands in two bad places, paste API keys everywhere and hope nothing leaks or skip real OAuth and fake the AI posted for you. We wanted something closer to a product niche-aware ideas, Gemini assisted drafts and real publishing to LinkedIn and Facebook while Google Calendar drives when it’s ok to post. For Google access, copying long-lived secrets into our DB felt wrong. Auth0 for AI Agents and Token Vault match that story, federated refresh material stays in Auth0’s trust boundary and our server only exchanges into short-lived tokens when we need Calendar (and related) APIs. We also saw a lot of generic AI writers. We focused on authorized agents, the app only acts when login, Token Vault, and user connections say it can.
What it does
Athena is a Phoenix web app that acts as an AI-powered brand assistant. Niches & trends or Brand Users define niche phrases; scheduled jobs propose topic ideas (default: Gemini-backed fetcher; swappable for RSS, News API, etc.). AI drafts Multiple variants, approval workflow, and paths toward schedule or publish. Agent settings IANA timezone, local weekdays and time windows; schedule is synced to Google Calendar so users see their posting windows and the agent can read upcoming slots. Posts Compose manually or from AI approve, smart-schedule (calendar-aware), retry failures, publish to connected platforms. Connections LinkedIn and Facebook via Auth0; Google uses Token Vault for Calendar (with optional Connected Accounts when extra federated consent is needed).
How we built it
We built Athena as a traditional server-rendered + LiveView app with background agents. Backend Elixir on Phoenix and Phoenix LiveView for dashboard, posts, niches, brand, connections, and agent settings. Jobs Oban runs trend discovery, content generation, publishing, and related workers on a cron-style schedule. Data PostgreSQL with Ecto session model for logged-in users. AI Google Gemini for topic and post generation, configuration supports retries/backoff for rate limits. Identity & Google APIs Auth0 (Universal Login) Token Vault + private key JWT for token exchange Management API for LinkedIn/Facebook identity tokens where that’s the supported path Req for HTTP. Frontend HEEx templates, Tailwind CSS, DaisyUI-style components; responsive shell with a mobile drawer for navigation.
Challenges we ran into
The hardest part was end-to-end Auth0 alignment grant types, connection purpose for Google (Token Vault vs login-only), JWKS and client authentication for the token endpoint, and Allowed Callback URLs that must match the app’s public URL (scheme, host, port)—including plain HTTP UAT vs HTTPS behind a proxy. Misconfiguration shows up as 401 on token exchange or silent session issues, which took careful logging and dashboard checks to untangle. A second challenge was UX across surfaces: a dense desktop nav doesn’t work on phones, so we iterated on layout and wrapping for filters and action rows, not only the global menu.
Accomplishments that we're proud of
Token Vault path for Google Calendar Posting windows grounded in real calendar data without hoarding Google OAuth secrets in our database. One Auth0 user, multiple platforms Linking identities and using the right token path per provider (Token Vault vs Management API) behind a single Connections story. Operational honesty Oban-backed pipelines, retries, and clear failure states on posts instead of “fire and forget” AI slop.
What we learned
The useful part of “AI agents” isn’t only the model it’s where consent and tokens live. Treating Auth0 as the system of record for federated access, and Gemini as a replaceable reasoning layer, kept the architecture auditable and deployable without turning our DB into a secret warehouse.
Bonus Blog Post
The first time we wired our AI agent to Google Calendar, nothing magical happened just a frustrating 401 from the token endpoint and vague “client authentication” errors in the logs. That’s when Token Vault stopped being a checkbox feature and became something we had to truly understand. We learned quickly that private key JWT wasn’t optional, JWKS had to align perfectly, and the Google connection needed more than “login” scope without the right purpose, the token exchange simply wouldn’t happen.
The real shift came when we separated trust from execution. Our backend, built in Elixir with Postgres, handles the logic, but we made a deliberate choice not to store sensitive refresh tokens ourselves. Token Vault became the boundary of trust securely holding credentials while our system only requests access when needed. This meant less risk, cleaner architecture, and a model that respects user consent.
The hardest part wasn’t the code it was alignment. Callback URLs, grant types, and credentials all had to match exactly across environments. Every small mismatch produced the same generic failure, forcing us to dig deeper into logs and truly understand the flow.
When it finally worked, it wasn’t just about creating calendar events it was proof that the system was secure, intentional, and built the right way.
What's next for Athena
This is a fresh submission built entirely during the hackathon.
Built With
- auth0-(universal-login
- bandit
- connected-accounts-/-my-account-api-as-needed)
- daisyui
- ecto
- elixir
- google-gemini-api
- management-api
- oban
- phoenix
- phoenix-liveview
- postgresql
- req
- tailwind-css
- token-vault
Log in or sign up for Devpost to join the conversation.