<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kim Maida</title>
    <description>The latest articles on DEV Community by Kim Maida (@kimmaida).</description>
    <link>https://dev.to/kimmaida</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F142453%2F2079a3c4-b091-425f-96b8-e4c68439ac29.png</url>
      <title>DEV Community: Kim Maida</title>
      <link>https://dev.to/kimmaida</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kimmaida"/>
    <language>en</language>
    <item>
      <title>I Built and Authorized a Planning Agent with MCP and Keycard</title>
      <dc:creator>Kim Maida</dc:creator>
      <pubDate>Wed, 11 Mar 2026 19:19:14 +0000</pubDate>
      <link>https://dev.to/kimmaida/i-built-a-secure-planning-agent-with-mcp-and-keycard-324a</link>
      <guid>https://dev.to/kimmaida/i-built-a-secure-planning-agent-with-mcp-and-keycard-324a</guid>
      <description>&lt;p&gt;My workday is scattered across many disconnected tools: Google Calendar, Linear, Gmail, Google Docs, GitHub, Slack, and Granola meeting notes. No single view answers "what should I work on right now?"&lt;/p&gt;

&lt;p&gt;AI is rapidly changing how we work. MCP servers, agents, and features like Claude Cowork can connect to many sources and help you plan your day through conversation, readily-available MCP servers, and tool integrations. But I have always prioritized and organized my work myself, mostly using a kludge of lists, various project management tools, Slack reminders, Gmail labels, and calendar blocking.&lt;/p&gt;

&lt;p&gt;This is always a mess, but it's &lt;em&gt;my&lt;/em&gt; mess. Pre-existing AI agents can help me aggregate data, but I still need to prioritize and analyze everything mentally. That's not a tool availability problem, it's a reasoning problem. And it's always been important to me that it's &lt;em&gt;my&lt;/em&gt; reasoning. I wanted a dashboard that doesn't just show everything, but thinks about it for me, and thinks about it the way I do.&lt;/p&gt;

&lt;p&gt;So I built an AI agent that reads all my work tools and helps me plan my day. But lots of people have done that, so more importantly: I did it without tearing my hair out or agonizing for weeks over the auth parts.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built: "Plan My Today"
&lt;/h2&gt;

&lt;p&gt;Plan My Today is a daily planning dashboard with an embedded chatbot I call "Todaygent." The Plan My Today MCP server calls many sources, finds todos, and drops them into a unified, prioritized view. Then Todaygent reasons about my priorities, blockers, and meeting prep using real data.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/76xm1awRKOA"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;As much as I spent time defining what Todaygent &lt;em&gt;can&lt;/em&gt; do, it was equally important to be crystal clear about what Todaygent &lt;em&gt;can't&lt;/em&gt; do. I've always been kind of a masochist about my messy task list... and I like the dopamine hit from manually checking something off. I don't want an agent to move my tasks around or mark tasks “Done.”&lt;/p&gt;

&lt;p&gt;All I want is something smart enough to plan and organize the way I would if I had an abundance of free time (which nobody has, right?). It doesn't even have to plan more than today. If I've learned one thing about my planning habits, it's that my day changes hour by hour. Any plan I make more than a day in advance flies right out the window. I like managing my own tasks at the source. It's just the day-planning across incredible tool sprawl I need help with.&lt;/p&gt;

&lt;p&gt;Todaygent has read-only access to every data source, and it's self-aware of its own limitations. It uses a local store to let me dismiss things that can’t be dismissed at the source (like meeting notes or Slack mentions).&lt;/p&gt;

&lt;p&gt;I also realized (through rigorous use) that I needed to hoist or reduce priority of specific tasks based on context I had as a human that wasn't captured in the cold, hard data. The MCP server has tools for each of these actions, and writes to a local JSON store to track my updates. For everything else (Linear, GitHub, Gmail, Calendar, and Slack messages I specifically mark), I own status changes in the source apps myself. Todaygent doesn't need write access to external tools to plan my day.&lt;/p&gt;

&lt;p&gt;The app dashboard has two views: priority-based (critical/high/medium/low) and source-based grouping, as well as light/dark/system themes, search, filter, and sort.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzs2qaqy1yxdnb1ch55sh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzs2qaqy1yxdnb1ch55sh.png" alt="Plan My Today dashboard - priority"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmiyltuuhpu3geoa2fcxt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmiyltuuhpu3geoa2fcxt.png" alt="Plan My Today dashboard - source"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;

&lt;p&gt;Plan My Today is architected like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzgvcjzs3sqqmfie2vfem.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzgvcjzs3sqqmfie2vfem.webp" alt="Plan My Today architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All MCP tools are managed through a central registry. Tools that touch external APIs follow a pattern: Zod schema → async handler → extract authInfo → &lt;a href="https://keycard.ai" rel="noopener noreferrer"&gt;Keycard&lt;/a&gt; token exchange → MCP-formatted response. One file per tool, registered through a &lt;code&gt;TOOL_REGISTRY&lt;/code&gt; array.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Aggregation Tool: &lt;code&gt;list-all-tasks-today&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is it: the tool that pulls from every third party source, scores priorities, and enriches tasks with cross-references.&lt;/p&gt;

&lt;p&gt;All sources are fetched concurrently with &lt;code&gt;Promise.allSettled()&lt;/code&gt;. Each fetch does its own Keycard token exchange (more on this in the auth section). Each task gets a priority score. Every source has its own scoring algorithm with different base scores and signal weights that I worked hard to tune, and if I notice something off, I tweak the weights and scoring as needed. Todaygent thinks like I do, and when it doesn't... I force it to. The MCP server cross-references related tasks to help Todaygent and preserve my sanity when I look at the dashboard.&lt;/p&gt;

&lt;p&gt;The expensive multi-source fetch (&lt;code&gt;list-all-tasks-today&lt;/code&gt;) writes to a local JSON file. A separate tool reads the local task list to give Todaygent and the dashboard the enriched task list on demand. I can trigger another &lt;code&gt;list-all-tasks-today&lt;/code&gt; if I add or complete tasks. No tokens wasted.&lt;/p&gt;

&lt;h3&gt;
  
  
  LLM in the backend
&lt;/h3&gt;

&lt;p&gt;Meeting notes are the messiest source because action items are often casually discussed in subtle ways regex can't detect. I debugged a bunch of missed items and false positives before adding LLM enhancement. The backend LLM does a second pass to catch conversational, implicit stuff. If I volunteer for (or agree to) something in natural conversation, an LLM can pick that up whereas regex can't.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Auth Challenge and How Keycard Solves It
&lt;/h2&gt;

&lt;p&gt;Even AI knows auth is the hard part. These 8 sources with 7 different resources each require token exchanges. This includes scoped grants for Google Calendar API, Gmail API, Drive API, Drive Activity API, Linear, GitHub, and Slack. The browser can't store API secrets safely. Building custom auth per provider would mean 7 separate OAuth implementations. I have a lot of experience in Identity and Access Management, and I know that's a ton of work where a lot can go wrong.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvj7mrvk3iuaciy79yuni.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvj7mrvk3iuaciy79yuni.webp" alt="Auth is hard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution: Keycard as the control plane for Todaygent
&lt;/h3&gt;

&lt;p&gt;Everything is handled by a single &lt;a href="https://keycard.ai" rel="noopener noreferrer"&gt;Keycard&lt;/a&gt; OAuth login using Google as the identity provider. The browser runs a PKCE flow and the client secret stays server-side in a confidential backend. After authenticating, I get one JSON Web Token (JWT) from Keycard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Token-Mediating Backend Architecture
&lt;/h3&gt;

&lt;p&gt;I made an architectural decision to use a Token-Mediating Backend (TMB). The React frontend saves the Keycard JWT in sessionStorage and sends it as a bearer token with every request to the Express backend. The backend does all the token exchange work: it uses the JWT to request provider-specific credentials, calls the APIs, and returns results. Tokens from the source services never touch the browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.keycard.ai/blog/i-built-a-secure-planning-agent-with-mcp-and-keycard#rfc-8693-token-exchange-the-key-mechanism" rel="noopener noreferrer"&gt;RFC 8693 Token Exchange&lt;/a&gt;: The Key Mechanism
&lt;/h3&gt;

&lt;p&gt;When a tool call requires third party API access, my Keycard JWT is exchanged for a provider-specific access token. My Keycard JWT is included, along with the resource URL that says which API I want access to. Keycard then gives me a short-lived access token for only the provider I need.&lt;/p&gt;

&lt;p&gt;But wait... Google stuff should all be under one OAuth provider, right? It is, but it's calling several APIs. Keycard issues ephemeral credentials that are scoped to the task. I don't want one over-privileged access token from Google with permissions for all those services. I want a token for read-only access to the Calendar API when Todaygent wants to look at Calendar, I want a token for read-only access to the Drive API when I want to see comments assigned to me... you get the idea. This is secure, leaves an explicit audit trail, and ensures Todaygent only gets what it needs for any given task. There's no standing access or over-privileged credentials.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Slack's "OAuth 2.0" implementation doesn't follow the OAuth 2.0 spec. Keycard supports unorthodox or custom "OAuth," but also has a pre-configured catalog of popular providers. When providers don't follow standards, Keycard just "makes it work" for you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Ephemeral Tokens and Performance
&lt;/h3&gt;

&lt;p&gt;Every tool call exchanges a fresh token from Keycard, uses it for the API call, and discards it. One token per action. Provider access tokens are never stored.&lt;/p&gt;

&lt;p&gt;This is how agent authorization should work: agents shouldn't hold onto credentials longer than they need to. Static secrets and long-lived tokens create unmonitored risk, which is exactly the problem Keycard is designed to solve.&lt;/p&gt;

&lt;p&gt;This is the core of how Keycard works: policy is evaluated when credentials are issued, not when they're used. If Keycard's policy says Todaygent shouldn't access my Gmail for this tool call, the Gmail API access token never exists. There's nothing to intercept because nothing was issued in the first place.&lt;/p&gt;

&lt;p&gt;"But aren’t all those token exchanges slow?"&lt;/p&gt;

&lt;p&gt;Not really, and here's why.&lt;/p&gt;

&lt;p&gt;Parallel exchange absorbs the latency. The list tool runs all token exchanges concurrently with &lt;code&gt;Promise.allSettled()&lt;/code&gt;. The latency cost is the slowest single exchange (~150–250ms), not the sum. I'm already waiting for the slowest API response anyway, and all the token exchanges finish well before all the API data comes back.&lt;/p&gt;

&lt;p&gt;The pattern is "fetch once, reason many times." The agent calls &lt;code&gt;list-all-tasks-today&lt;/code&gt; once per conversation, then reasons about the results across multiple chat turns without re-fetching. One credential set per aggregation call, then no more credentials. Todaygent has per-source MCP tools too, and gets an appropriately scoped access token when it calls the tools individually.&lt;/p&gt;

&lt;p&gt;The performance cost of ephemeral credentials in the initial multi-provider tool call is ~150–250ms per dashboard load. That's a heck of a good trade for zero credential reuse.&lt;/p&gt;

&lt;h2&gt;
  
  
  Visibility: What Todaygent Actually Did
&lt;/h2&gt;

&lt;p&gt;One of Keycard's most compelling features is the information it provides. Every token exchange, every user authorization, every credential issued, every resource accessed is logged in the Keycard audit log. When I open the Keycard console after a dashboard load, I can see exactly what Todaygent touched.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Audit Log
&lt;/h3&gt;

&lt;p&gt;Keycard’s audit log shows the entire chronological stream of events. After a single &lt;code&gt;list-all-tasks-today&lt;/code&gt; call, several token exchange events are logged. They fire in quick succession from the parallel &lt;code&gt;Promise.allSettled()&lt;/code&gt; fetch.&lt;/p&gt;

&lt;p&gt;But the most interesting part is the identity chain, which shows two identities: the Application ("Plan My Today") and the User (my email). This is the complete trail: which app, acting on behalf of which human, accessed which resource.&lt;/p&gt;

&lt;p&gt;The grant type (token exchange, not a direct OAuth flow), the credential provider (Google), the exact scopes granted, the issuance timestamp, and the resource are all tied back to the identity chain. I know exactly what Todaygent did.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyu2mw9r4b017b6fhax0c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyu2mw9r4b017b6fhax0c.png" alt="Keycard audit log"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I log in and authorize Plan My Today to access my Calendar, Gmail, and so on, Keycard logs user authorization events. Authorize events are triggered by the human, not Todaygent, because I’m giving permission to access my resources.&lt;/p&gt;

&lt;p&gt;The distinction matters: user authorization is consent ("I'm allowing this app to access my Gmail"). Credential issuance is execution ("Todaygent just exchanged a token to read my Gmail"). Two different events, two different actors, both fully traceable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sessions and Grants
&lt;/h3&gt;

&lt;p&gt;Keycard’s audit log gives me event details and higher-level information. I can also see what Todaygent did during a specific work session: which APIs it touched, how many times, and when. If something looks off, I can inspect the audit log for the full session event trail.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6fma85kbmwae9qo0y9q8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6fma85kbmwae9qo0y9q8.png" alt="Keycard sessions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Grants are the kill switch. I can revoke a grant for a single resource without nuking the entire session: Todaygent's next token exchange for that resource fails, but everything else keeps working. For Plan My Today, grants are ephemeral by design: they expire after each provider token's lifetime. In a production environment with longer-lived grants, surgical revocation is the difference between "turn everything off" and "cut off Gmail access but Calendar and Linear keep working."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fekgvbq228rfy5obzrn77.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fekgvbq228rfy5obzrn77.png" alt="Keycard grants"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Matters for Agent-Native Apps
&lt;/h3&gt;

&lt;p&gt;Traditional auth gives you two user states: the user is logged in, or they're not. That's simply not enough when you have thinking agents acting within your systems. You might have access logs on your own server, but you don't have visibility into what tokens were issued, to which agent, for which resource, on behalf of which user. Access logs tell you what happened, but Keycard's audit log tells you what was authorized to happen, before the event takes place.&lt;/p&gt;

&lt;p&gt;I built Plan My Today with two goals: plan my day (obviously), and avoid the staggering complexity of multi-tool agent access by using Keycard. It's my dogfood project. (Though internally at Keycard, we like to say we're drinking our own champagne; the metaphor is less gross.) Plan My Today demonstrates Keycard's core model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Task-scoped credentials: one token per API call&lt;/li&gt;
&lt;li&gt;Composite identity: user + agent + resource in every request&lt;/li&gt;
&lt;li&gt;Zero standing access: no cached resource tokens, no long-lived secrets&lt;/li&gt;
&lt;li&gt;Delegation chains: every action traces back to me&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keycard's audit log gives me the full chain: user → application → resource, with every token exchange and authorization event logged and queryable. For an app like Plan My Today that touches many different APIs on my behalf, this isn't optional. For secure agent development and deployment, this is how I answer "what did the agent do with my data?" with actual evidence instead of blind trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI Agent: Todaygent
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Personality and Philosophy
&lt;/h3&gt;

&lt;p&gt;Todaygent is "a planner, not a doer." It reads everything and acts on almost nothing. I wanted Todaygent to have dry wit and be self-aware of its own limitations, so when I ask it to do something outside its scope, it'll say something like "My maker didn't trust me with permission to do that."&lt;/p&gt;

&lt;p&gt;Permission Model (Intentionally Restricted)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Read freely&lt;/strong&gt; (all read tools) - fetch any of the data sources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask before acting&lt;/strong&gt; - &lt;code&gt;dismiss-task&lt;/code&gt;: dismiss meeting notes, docs, Slack mentions, and adhoc tasks (local store, no API credentials needed); &lt;code&gt;restore-dismissed-task&lt;/code&gt;: undo a dismissal; &lt;code&gt;set-task-priority&lt;/code&gt;: boost or demote any task's priority when I ask to reprioritize (local store)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intentionally unavailable&lt;/strong&gt; - Linear status changes, GitHub actions, email labeling, Slack emoji removal, email sending, calendar modifications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a trust design decision. A planning agent that can read my work and help me think is useful. An agent that can modify my work without guardrails is dangerous. Using least privilege means I can let Todaygent run without worrying about it marking my Linear issues "Done" or auto-replying to emails, even if I accidentally tell it to do something it shouldn't. Or if I tell it on purpose... sometimes I do that just to see how it responds. (Come on, doesn't everyone?) That's the confidence I have in my Keycard implementation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flopbkrplflgh6qvh3op1.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flopbkrplflgh6qvh3op1.webp" alt="Todaygent refusing to take action outside its permissions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Agentic Loop
&lt;/h3&gt;

&lt;p&gt;The chat implementation lives in a React hook that manages the full agentic loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;User sends message
  → Stream Todaygent response &lt;span class="o"&gt;(&lt;/span&gt;with all tools available&lt;span class="o"&gt;)&lt;/span&gt;
    → If Todaygent calls tools, execute via MCP
      → Feed results back to Todaygent
        → Loop &lt;span class="o"&gt;(&lt;/span&gt;max 10 rounds&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are lots of ways for things to go off the rails with Todaygent, so I was specific. A max tool-call limit prevents infinite loops. Tool result truncation keeps one API response from dominating the conversation. Prompt caching saves tokens on every turn. Adaptive thinking on Claude Opus 4.6 lets Todaygent use extended thinking for complex planning. Finally, context management uses Anthropic's API instead of manual conversation windowing.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I Ask It
&lt;/h3&gt;

&lt;p&gt;If I tell Todaygent to plan my day, I get a briefing with a time-blocked schedule, dependency analysis, and cross-source context. I can ask it for blockers, productivity advice, or even haikus about my task list.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/DfzISjUqOIE"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h3&gt;
  
  
  Importance of the System Prompt
&lt;/h3&gt;

&lt;p&gt;Todaygent's system prompt isn't "be helpful." It's very thorough and defines the permission model, personality, formatting rules, tool-calling strategy, and edge cases. It tells Todaygent when to fetch fresh data vs. reason from existing context, and how to behave when it can't do something. Early on, Todaygent was super eager to help but chaotic: it would re-fetch data mid-conversation, forget to include links, or confidently hallucinate that it successfully did things it had no tools or permissions for.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;I use Todaygent every day, several times a day (because plans I make in the morning are never my plans anymore by the afternoon). It's a personal work tool I use on my work machine, tailored to the specific way I work. There's no reason to deploy it to the public internet or support multi-tenancy. My SaaS sprawl is bad enough as it is.&lt;/p&gt;

&lt;p&gt;But I &lt;em&gt;did&lt;/em&gt; implement a quality-of-life enhancement: I turned Plan My Today into a Progressive Web App (PWA) so I can install it as a desktop app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6bl5bissrqjutqhy1xg9.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6bl5bissrqjutqhy1xg9.webp" alt="Plan My Today as a PWA"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My Plan My Today agent-programming lessons are never done. I've learned that the mental processing I subconsciously do to organize my day is incredibly complex. Trying to make something not-me emulate it reliably is a monumental, neverending task.&lt;/p&gt;

&lt;p&gt;That tells me quite a bit about where AI is at right now, and how much we still need human reasoning in the loop. Sometimes I wonder if I'm actually saving myself any time. At least it's a very satisfying thing to hack on.&lt;/p&gt;

&lt;p&gt;If you're building agent-native apps that need to access multiple APIs on behalf of users, Keycard will save you from implementing OAuth per provider. I have a career in identity (which I love!) and even so, I smile to myself just thinking about the OAuth delegation and access nightmare I'm avoiding by using Keycard. One login authorizes every provider and issues policy-aware, ephemeral, task-scoped tokens for each source your agent needs. You can track the full agent and human delegation chain and surgically revoke grants when necessary.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://keycard.ai" rel="noopener noreferrer"&gt;Keycard is currently in Early Access&lt;/a&gt;, so you can sign up to work closely with our team on your own multi-service agent apps (it's awesome).&lt;/p&gt;

&lt;p&gt;I'm steadily collecting backlogged Linear tasks with ideas for Plan My Today improvements: more sources, new tools, UI improvements, better docs. I already use Plan My Today every day. Now it's about expanding what Todaygent can see and (carefully) do, and even more importantly, incorporating new Keycard features into my &lt;del&gt;dogfood&lt;/del&gt; "champagne" project.&lt;/p&gt;

&lt;p&gt;And of course, Todaygent is constantly reminding me I have pending tasks to keep improving it.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>mcp</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
    <item>
      <title>The Day Agents Achieved Real Authority, and What It Means for Trust</title>
      <dc:creator>Kim Maida</dc:creator>
      <pubDate>Wed, 25 Feb 2026 19:37:13 +0000</pubDate>
      <link>https://dev.to/kimmaida/the-day-agents-achieved-real-authority-and-what-it-means-for-trust-2e4</link>
      <guid>https://dev.to/kimmaida/the-day-agents-achieved-real-authority-and-what-it-means-for-trust-2e4</guid>
      <description>&lt;p&gt;Five major announcements landed on a single Monday in February, and just like that, it became very clear to me that AI agents are no longer experiments: they have real authority. And that’s scary, but at the same time, lots of work in trust infrastructure is going into eliminating the risk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;February 24, 2026, 10:45pm ET&lt;/strong&gt;: I was working on my in-development event ROI MCP server + agent (named ROIBOT, obviously). I was sitting there staring dead-eyed into my screen and clicking "Allow Once" in Claude Code (spoiler: it's not once; it's &lt;em&gt;never&lt;/em&gt; once) &lt;em&gt;fifty thousand times&lt;/em&gt; for &lt;code&gt;grep&lt;/code&gt;. I don't want to know how many hours I've spent shackled to my desk because I need to &lt;code&gt;⌘&lt;/code&gt;+&lt;code&gt;↵&lt;/code&gt; my night away while getting more snippy with Claude proportional to the number of times I've had to "allow once."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzeajzz5qujv2z7qaanho.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzeajzz5qujv2z7qaanho.png" alt="being snippy with Claude" width="800" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Since this was published, I've discovered &lt;a href="https://code.claude.com/docs/en/permissions" rel="noopener noreferrer"&gt;permission configuration for Claude Code&lt;/a&gt;, which I highly recommend.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In my boredom, a tweet crossed my feed that perked me right up: &lt;a href="https://x.com/claudeai/status/2026418433911603668" rel="noopener noreferrer"&gt;Claude Code is getting Remote Control&lt;/a&gt;. At the time of this writing (it's still February 24 at the moment), it's in Research Preview for Max users. I'm not on an individual plan, so it's out of reach for me right now, but dang it, I'm excited. The sheer &lt;em&gt;time reclamation&lt;/em&gt; I am going to get from that.&lt;/p&gt;

&lt;p&gt;So then I went down a rabbit hole (because I'm still stuck here clicking "Allow Once"). I work at &lt;a href="https://keycard.ai" rel="noopener noreferrer"&gt;Keycard&lt;/a&gt; and &lt;a href="https://www.keycard.ai/blog/keycard-joins-the-agentic-ai-foundation" rel="noopener noreferrer"&gt;we just announced that we joined the Agentic AI Foundation (AAIF)&lt;/a&gt;, and I felt a little more lively after seeing the Claude Code Remote Control announcement. I checked out other news from the day.&lt;/p&gt;

&lt;p&gt;And wow. It's been a busy day. Not just because of the announcements themselves, but because these announcements have teeth. Collectively, they &lt;em&gt;mean&lt;/em&gt; something: AI agents aren't experiments anymore. Agents are executing real business workflows, high-stakes financial transactions, and running untethered. All those things make trust infrastructure &lt;em&gt;absolutely non-negotiable&lt;/em&gt;. And also a bottleneck.&lt;/p&gt;

&lt;p&gt;So what all happened today anyway?&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Claude Code got Remote Control&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This is my favorite announcement of the day.&lt;/p&gt;

&lt;p&gt;Anthropic released &lt;a href="https://code.claude.com/docs/en/remote-control" rel="noopener noreferrer"&gt;Remote Control&lt;/a&gt; into research preview. You start a code task in the terminal, then &lt;em&gt;walk away from your desk&lt;/em&gt; and keep controlling the session from &lt;del&gt;your phone&lt;/del&gt; "any device." Claude keeps running on your local machine while you give commands from anywhere.&lt;/p&gt;

&lt;p&gt;And yeah, that'll make me look at my phone way too much, but hopefully they'll also change "Allow Once" to "Always Allow for Session" for read actions soon too. And at least I won't be melting into my computer chair anymore.&lt;/p&gt;

&lt;p&gt;Think about what that means for trust though. That's a local agent accepting remote commands through an authenticated cloud relay. The session is untethered from the machine on the desk. The context, filesystem, &lt;code&gt;.env&lt;/code&gt; secrets, MCP servers, all of it stays active &lt;em&gt;while the human is somewhere else entirely&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That's a heck of a delegation infra requirement.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Anthropic shipped enterprise agent plugins&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://claude.com/blog/cowork-plugins-across-enterprise" rel="noopener noreferrer"&gt;Anthropic also launched a new enterprise agents program&lt;/a&gt; with out-of-the-box plugins for finance, engineering, and design. That means production-ready agents that execute workflows, submit expenses, generate reports, and manage compliance reviews. Anthropic's head of Americas dropped this quote: "2025 was meant to be the year agents transformed the enterprise, but the hype turned out to be mostly premature. It wasn't a failure of effort. It was a failure of approach."&lt;/p&gt;

&lt;p&gt;The reason we're starting to see results is because the approach is changing. Agents are getting real authority inside organizations. (Yay...? Or maybe: scary!)&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Docusign brought agreement workflows to Cowork&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.docusign.com/en-gb/blog/docusign-and-anthropic-bringing-intelligent-contract-workflows-to-cowork" rel="noopener noreferrer"&gt;Docusign's new MCP connector&lt;/a&gt; lets agents create, review, send, and manage contracts using natural language in Claude Cowork. Not summarize contracts so you can review them more easily. &lt;em&gt;Execute&lt;/em&gt; contracts. The connector is built on MCP with permission-based access and platform authentication.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;As an aside, they're calling this "Intelligent Agreement Management" and now I need to remember another "&lt;a href="https://en.wikipedia.org/wiki/Identity_and_access_management" rel="noopener noreferrer"&gt;IAM&lt;/a&gt;" acronym.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On a serious note though, that feels on the verge of dystopian to me, and I'm all-in on AI at this point (in tech, not in art, but I'll shelve &lt;em&gt;that&lt;/em&gt; gnarly topic). It's a robot signing a legally binding agreement on your behalf. That means &lt;em&gt;for&lt;/em&gt; you. &lt;em&gt;As&lt;/em&gt; you.&lt;/p&gt;

&lt;p&gt;We already have a &lt;a href="https://theshamblog.com/an-ai-agent-published-a-hit-piece-on-me/" rel="noopener noreferrer"&gt;pretty serious problem with rampant OpenClaw agents&lt;/a&gt;. Now imagine if that ungoverned agent was yours, and it autonomously decided you should sign an enterprise SaaS contract for the modest price of a million dollars. That's your signature, given away freely, maybe without you even knowing it.&lt;/p&gt;

&lt;p&gt;Clearly governance is needed, but so is zero standing access.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Vouched launched Agent Checkpoint&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Vouched shipped &lt;a href="https://kya.vouched.id" rel="noopener noreferrer"&gt;Agent Checkpoint&lt;/a&gt;. Agent Checkpoint lets you add a pixel to your HTML (like a marketing pixel!) to detect agents accessing your site. Vouched CEO Peter Horadan laid it out: "Every website is realizing they now have AI agents coming through their login button, using the username and password of humans. These sites have no way to tell agents apart from humans, or even to know if a given agent is trustworthy. Agents are breaking all the prior rules of cybersecurity."&lt;/p&gt;

&lt;p&gt;There's been an explosion of market and industry activity because we've reached a point where we're overstretching. If we don't take preventative action, when this stretch springs back, it's going to &lt;em&gt;hurt&lt;/em&gt;. Today was a good example of how we're catching up to a problem that's been building for months.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The AAIF is growing fast&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://aaif.io/press/agentic-ai-foundation-welcomes-97-new-members-as-demand-for-open-collaborative-agent-standardization-increases/" rel="noopener noreferrer"&gt;Agentic AI Foundation announced 97 new members today&lt;/a&gt;. That brings the count up to 146 organizations, and keep in mind, the AAIF was just founded December 9, 2025. New members include JPMorgan Chase, American Express, Red Hat, ServiceNow, Lenovo, Akamai, Autodesk, &lt;a href="https://keycard.ai" rel="noopener noreferrer"&gt;Keycard&lt;/a&gt;, and more.&lt;/p&gt;

&lt;p&gt;I work at Keycard. We joined as a Gold Member because the protocols and standards emerging right now will define this incredible generation of software. Agent identity and control absolutely should be built openly. I'm a nerd for open standards (when I'm tempted to spiral into doomscrolling, I read RFCs instead), and I think this is great.&lt;/p&gt;

&lt;p&gt;In my career so far in Identity and Access Management (IAM), I never imagined working at the cutting edge as desperately needed new governance and standards form in real time. Traditional IAM isn't particularly known for &lt;em&gt;moving quickly&lt;/em&gt;. I mean, OAuth 2.0 is over 13 years old, and &lt;a href="https://datatracker.ietf.org/doc/draft-ietf-oauth-v2-1/" rel="noopener noreferrer"&gt;OAuth 2.1 is &lt;em&gt;still&lt;/em&gt; a draft&lt;/a&gt;, not an RFC.&lt;/p&gt;

&lt;p&gt;And now we're at the table where MCP and agent auth and governance are taking shape. I honestly haven't been &lt;em&gt;this&lt;/em&gt; excited about my chosen industry in a long time.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What does it all mean?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Everything announced today collectively sharpens into this point: agents have &lt;strong&gt;real authority&lt;/strong&gt; now. They execute legal contracts, manage infrastructure, run untethered from desks, and freely operate across trust boundaries that human IAM was never designed for.&lt;/p&gt;

&lt;p&gt;Static credentials need to be a thing of the past. Long-lived, user-scoped tokens have transformed from comfy, familiar auth into a liability. Agents make decisions at machine speeds. They act across clouds, APIs, and services. And the tech industry has managed to figure out that human identity doesn't cut it in this brave new agentic world.&lt;/p&gt;

&lt;p&gt;There are even parallels in video games and sci-fi: content that, when it came out, was meant to take place hundreds of years from now. I used to play a lot of Halo. And something that Cortana (a sentient AI) says to Master Chief is suddenly becoming a very real truth that &lt;em&gt;feels&lt;/em&gt; surreal. Like we're living in the future.&lt;/p&gt;

&lt;p&gt;She says there's no cure for &lt;a href="https://www.halopedia.org/Rampancy" rel="noopener noreferrer"&gt;rampancy&lt;/a&gt;. Once an AI goes rampant, there's no way to restore it to its previous state and it must be destroyed to prevent it from harming itself and others. And now there are actual &lt;a href="https://www.nytimes.com/2026/02/23/opinion/chatbots-open-claw.html" rel="noopener noreferrer"&gt;AI agents running rampant out there doing destructive things&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can actually make a decision now about whether you want to clean up the aftermath, or prevent the incident from happening in the first place. Evaluating policy when short-lived, task-scoped credentials are &lt;em&gt;issued&lt;/em&gt; gives agents zero standing access, and that's pretty helpful for prevention.&lt;/p&gt;

&lt;p&gt;It's what my company does, and while humanity's whole worldview turns into something straight out of science fiction, I'm glad I'm helping to protect people's identities, data, software, APIs, legal liability, bank accounts, and everything to come.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>agents</category>
    </item>
    <item>
      <title>OAuth 2.0 Security Best Practices for Developers</title>
      <dc:creator>Kim Maida</dc:creator>
      <pubDate>Thu, 10 Apr 2025 16:16:21 +0000</pubDate>
      <link>https://dev.to/kimmaida/oauth-20-security-best-practices-for-developers-2ba5</link>
      <guid>https://dev.to/kimmaida/oauth-20-security-best-practices-for-developers-2ba5</guid>
      <description>&lt;p&gt;In January 2025, the IETF (Internet Engineering Task Force) standards body published the &lt;a href="https://www.rfc-editor.org/rfc/rfc9700.html" rel="noopener noreferrer"&gt;Best Current Practice for OAuth 2.0 Security&lt;/a&gt;. It’s been over a decade since the &lt;a href="https://www.rfc-editor.org/rfc/rfc6749.html" rel="noopener noreferrer"&gt;OAuth 2.0 Authorization Framework&lt;/a&gt; was established in 2012. Since then, technology has advanced on all fronts: applications and access management have become more complex, security has evolved, and security attacks have become more sophisticated.&lt;/p&gt;

&lt;p&gt;OAuth 2.0 is broadly used for delegated authorization, and &lt;a href="https://openid.net/specs/openid-connect-core-1_0.html" rel="noopener noreferrer"&gt;OpenID Connect&lt;/a&gt; (OIDC: an authentication protocol extending OAuth 2.0) is relied upon for countless logins. Best practices for OAuth 2.0 and OIDC have evolved continually over the years, and &lt;a href="https://www.rfc-editor.org/rfc/rfc9700.html" rel="noopener noreferrer"&gt;RFC 9700: Best Current Practice for OAuth 2.0 Security&lt;/a&gt; is a culmination of that work thus far.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this article, I have summarized the Best Current Practice for OAuth 2.0 Security, condensing the contents into a (hopefully) more approachable format. &lt;/p&gt;

&lt;h3&gt;
  
  
  Target audience
&lt;/h3&gt;

&lt;p&gt;The target audience for this overview is developers on the client side of OAuth implementation. Some sections of the complete spec are not summarized here: best practices for authorization server providers are not covered in-depth because this article is to help developers who are adding OAuth 2.0 (and/or OIDC) capabilities to their applications. If you are an authorization server provider, please see &lt;a href="https://www.rfc-editor.org/rfc/rfc9700.html" rel="noopener noreferrer"&gt;the full OAuth 2.0 Best Practices specification&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4o0aiwrkh77ws7u24f33.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4o0aiwrkh77ws7u24f33.png" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Assumed knowledge
&lt;/h3&gt;

&lt;p&gt;This overview assumes basic familiarity with &lt;a href="https://www.rfc-editor.org/rfc/rfc6749.html" rel="noopener noreferrer"&gt;OAuth 2.0&lt;/a&gt; and, to a lesser extent, &lt;a href="https://openid.net/specs/openid-connect-core-1_0.html" rel="noopener noreferrer"&gt;OpenID Connect&lt;/a&gt;. It assumes you understand the parties involved and their roles (e.g., client, authorization server, resource server, etc.), authorization flows, and related entities (e.g., access token, ID token, authorization code, etc.).&lt;/p&gt;

&lt;p&gt;Throughout the overview, I have included supporting links so readers can quickly access additional resources. If there are places where more resources or explanation would be helpful, &lt;a href="https://maida.kim/bio/#contact" rel="noopener noreferrer"&gt;please let me know&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Terminology
&lt;/h3&gt;

&lt;p&gt;I have done my best to simplify industry speak, to a logical extent. Of course, internet specifications are steeped in jargon, so this article assumes awareness of commonly used Identity and Access Management terms.&lt;/p&gt;

&lt;p&gt;Some terms may be ambiguous to readers who are familiar with how OAuth 2.0 works but less familiar with the specification itself. Some of those terms are defined below. Please let me know if there are more definitions that would be helpful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Confidential client&lt;/strong&gt;: an application running in a centralized location capable of securely storing secrets (e.g., a traditional backend web app)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Public client&lt;/strong&gt;: an application running on a user’s device, not capable of securely storing secrets (e.g., Single Page Apps, mobile apps)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Browser-based client&lt;/strong&gt;: an application running in the user’s browser (e.g., Single Page Apps, static sites)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resource owner&lt;/strong&gt;: the user granting access to some of their resources (e.g., data, actions, etc.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resource server&lt;/strong&gt;: an API that receives and verifies requests and access tokens to handle appropriate access to data (e.g., your own API, Google Maps, Firebase, etc.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do we need new best practices for OAuth 2.0?
&lt;/h2&gt;

&lt;p&gt;As mentioned above, technology has evolved since OAuth 2.0 was established, and its usage has expanded tremendously. What are some of the newer concerns that the original &lt;a href="https://www.rfc-editor.org/rfc/rfc6749.html" rel="noopener noreferrer"&gt;OAuth 2.0 Authorization Framework specification&lt;/a&gt; did not address?&lt;/p&gt;

&lt;p&gt;Whenever security standards are put in place, attackers will exploit any weaknesses they can find. OAuth has been around for over ten years, which is more than enough time for attackers to discover and take advantage of implementation weaknesses and anti-patterns. OAuth is also being used in environments with high security requirements, like open banking, healthcare, government, and electronic signatures. OAuth 2.0 doesn’t address the necessary precautions needed for this level of security.&lt;/p&gt;

&lt;p&gt;OAuth is also being used in more complex and dynamic setups. The standard was established when the relationships between applications, authorization servers, and APIs were more static. Apps knew server URLs at deployment time. However, now clients can access multiple service providers, and &lt;a href="https://en.wikipedia.org/wiki/Multitenancy" rel="noopener noreferrer"&gt;multitenant&lt;/a&gt; environments are common. As these complexities evolved, extensions of OAuth 2.0 were developed to support dynamic scenarios, such as &lt;a href="https://www.rfc-editor.org/rfc/rfc7591.html" rel="noopener noreferrer"&gt;OAuth 2.0 Dynamic Client Registration Protocol&lt;/a&gt; and &lt;a href="https://www.rfc-editor.org/rfc/rfc8414.html" rel="noopener noreferrer"&gt;OAuth 2.0 Authorization Server Metadata&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In addition, internet technology has changed. For example, browsers no longer handle redirection fragments the same way. These kinds of technology changes impact the security model that OAuth 2.0 relies on.&lt;/p&gt;

&lt;p&gt;The best current practices give security recommendations, new requirements, and deprecations to address the current state of authorization and authentication with OAuth 2.0 and OIDC. Best practices will be incorporated into &lt;a href="https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12" rel="noopener noreferrer"&gt;OAuth 2.1&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Protect redirect flows
&lt;/h2&gt;

&lt;p&gt;In some OAuth 2.0 and OIDC flows, the user is redirected in the browser to complete steps for authorization, authentication, and consent. You (as the implementer) configure redirect URIs that the authorization server uses to transmit information between itself and your app (like an authorization code), and to redirect users once they’ve completed an action (like logging in).&lt;/p&gt;

&lt;p&gt;For example, in the &lt;a href="https://www.rfc-editor.org/rfc/rfc6749#section-4.1" rel="noopener noreferrer"&gt;authorization code flow&lt;/a&gt;, the authorization server sends a code to the app in the browser in a query parameter. The app uses this code to request access tokens and/or ID tokens. After the user logs in successfully with the authorization server, they are redirected to a page in your application that you specify.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiq88uudwt0xfzdxozpab.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiq88uudwt0xfzdxozpab.png" alt="redirect URI" width="800" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Redirects are targets of attack because they can be hijacked if not configured properly. An attacker could redirect the authorization code to their own domain (instead of yours) and then impersonate a public app and exchange the code with the authorization server for tokens.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do not redirect to URIs obtained from a query parameter
&lt;/h3&gt;

&lt;p&gt;Clients and authorization servers must not redirect to URIs obtained from a query parameter, as these can be tampered with. For example, consider the following URI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://your-site.com/login?redirect_url=https://yuor-site.com/account
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The redirect will actually send the user to &lt;code&gt;yuor-site.com&lt;/code&gt; instead of &lt;code&gt;your-site.com&lt;/code&gt;. Because the URLs are similar, the user may not even notice the difference. This is called an open redirect: the user has control over the redirect since it’s clearly visible (and can be modified) in the URL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use exact string matching when configuring allowed redirect URIs
&lt;/h3&gt;

&lt;p&gt;Authorization servers should require exact string matching when accepting user configured allowed redirect URIs, as opposed to pattern-matching. Unsafe patterns or naive implementations on the authorization server can result in unwanted outcomes. For example, consider the following pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://*.your-site.com/*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The intent here is to allow any subdomain of your-site and any subpage of &lt;code&gt;your-site&lt;/code&gt; as a redirect, but if the authorization server interprets the wildcard &lt;code&gt;*&lt;/code&gt; as “any character” instead of “any character valid for a domain name,” something like &lt;code&gt;https://attacker.com/.your-site.com&lt;/code&gt; could be valid based on this pattern. Alternately, an attacker could establish a subdomain that would be allowed by this pattern even if it is implemented properly.&lt;/p&gt;

&lt;p&gt;Authorization servers should ensure exact string matching is required, but if your authorization server does allow pattern-matching, don’t use it. Instead, only add exact URLs to the authorization server’s list of allowed redirect URIs. The only exception to this is for ports on &lt;code&gt;localhost&lt;/code&gt; for native apps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Protect against Cross Site Request Forgery (CSRF) attacks
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://owasp.org/www-community/attacks/csrf" rel="noopener noreferrer"&gt;CSRF&lt;/a&gt; attacks are malicious requests that come from somewhere other than the authorization server. OAuth 2.0 and OIDC provide methods to mitigate CSRF attacks. Best practices state that CSRF protection must be implemented.&lt;/p&gt;

&lt;p&gt;OAuth 2.0 &lt;a href="https://www.rfc-editor.org/rfc/rfc7636.html" rel="noopener noreferrer"&gt;Proof Key for Code Exchange (PKCE)&lt;/a&gt; or OIDC &lt;a href="https://openid.net/specs/openid-connect-core-1_0.html#NonceNotes" rel="noopener noreferrer"&gt;nonce&lt;/a&gt; are both sufficient measures to protect against CSRF attacks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validate token issuer when using more than one authorization server
&lt;/h3&gt;

&lt;p&gt;Clients using more than one authorization server should validate the issuer (the authorization server that issued the token) &lt;code&gt;iss&lt;/code&gt; parameter in any tokens they receive. This ensures interaction with the correct authorization server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authorization Code Grant
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fopqs3pem4d6l6qnuj2q3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fopqs3pem4d6l6qnuj2q3.png" alt="shield key" width="200" height="215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Public clients must use Proof Key for Code Exchange
&lt;/h4&gt;

&lt;p&gt;Public clients (like native apps or browser-based apps) using OAuth 2.0 must use &lt;a href="https://www.rfc-editor.org/rfc/rfc7636.html" rel="noopener noreferrer"&gt;Proof Key for Code Exchange&lt;/a&gt; with the authorization code grant. PKCE (pronounced “pixie”) adds an additional layer of security to the authorization code exchange between your app and the authorization server.&lt;/p&gt;

&lt;p&gt;With PKCE, the app creates a random string (called the &lt;code&gt;code_verifier&lt;/code&gt;) for each authorization request. It then hashes the &lt;code&gt;code verifier&lt;/code&gt; using a hashing function called a &lt;code&gt;code_challenge_method&lt;/code&gt;. Hashing is irreversible: once a string has been hashed, it’s impossible to retrieve the original input. The app sends the &lt;code&gt;code_challenge&lt;/code&gt; and the &lt;code&gt;code_challenge_method&lt;/code&gt; to the authorization server along with the authorization request.&lt;/p&gt;

&lt;p&gt;Now the authorization server knows the &lt;code&gt;code_challenge&lt;/code&gt; (the hashed &lt;code&gt;code_verifier&lt;/code&gt;) and the &lt;code&gt;code_challenge_method&lt;/code&gt; (the hashing method used to create the &lt;code&gt;code_challenge&lt;/code&gt;). The authorization server then creates a &lt;code&gt;code&lt;/code&gt; and associates the &lt;code&gt;code_challenge&lt;/code&gt; and &lt;code&gt;code_challenge_method&lt;/code&gt; with the &lt;code&gt;code&lt;/code&gt;. It sends the &lt;code&gt;code&lt;/code&gt; to the app in a query parameter.&lt;/p&gt;

&lt;p&gt;The app takes the &lt;code&gt;code&lt;/code&gt; and the &lt;code&gt;code_verifier&lt;/code&gt; (the original, unmodified string) and sends them to the authorization server with an access token request. Although the authorization server can’t “un-hash” the &lt;code&gt;code_challenge&lt;/code&gt;, it now has everything it needs to repeat the same hashing steps the app took before the app sent the authorization request.&lt;/p&gt;

&lt;p&gt;The authorization server uses the &lt;code&gt;code_challenge_method&lt;/code&gt; to hash the &lt;code&gt;code_verifier&lt;/code&gt; and then compares the hashed output to the &lt;code&gt;code_challenge&lt;/code&gt; it received from the app earlier. If the output matches the &lt;code&gt;code_challenge&lt;/code&gt;, the request is legitimate, and the authorization server issues tokens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Confidential clients (such as traditional web apps) &lt;em&gt;should&lt;/em&gt; also use PKCE.&lt;/strong&gt; PKCE protects against CSRF and authorization code injection, an attack where an attacker tries to exchange a stolen authorization code for tokens. In OAuth 2.1, all apps (public and confidential) using authorization code grant will be required to use PKCE.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do not use implicit grant
&lt;/h3&gt;

&lt;p&gt;In implicit grant, tokens are delivered to a public app in the browser in a query parameter. All public apps must use authorization code grant with PKCE. Implicit grant must not be used. It’s not secure to expose tokens in a browser URL where they can easily be accessed and stolen.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Prevent token replay
&lt;/h2&gt;

&lt;p&gt;Token replay is when an attacker attempts to re-use another user’s token to gain access to protected resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use sender constrained access tokens
&lt;/h3&gt;

&lt;p&gt;In order to prevent token replay, access tokens should be sender constrained. Sender constraint scopes a token to a specific sender (e.g., the authorization server that issued the token). The token recipient (e.g., a protected API) will only accept a token if the sender can prove they know the necessary secret. Methods of sender constraint include &lt;a href="https://www.rfc-editor.org/rfc/rfc8705.html" rel="noopener noreferrer"&gt;mutual TLS&lt;/a&gt; or &lt;a href="https://www.rfc-editor.org/rfc/rfc9449.html" rel="noopener noreferrer"&gt;Demonstrating Proof of Possession&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Public client refresh tokens must be sender constrained or rotated
&lt;/h3&gt;

&lt;p&gt;Public clients, such as browser-based or native applications, must also implement sender constraint for refresh tokens. Refresh tokens are long-lived. They are used to keep a user’s access valid without forcing them to manually reauthenticate every time the short-lived access token expires. Because of their longevity and use case, they are prime targets for exploitation. Sender constraining refresh tokens protects them from being used in CSRF attacks.&lt;/p&gt;

&lt;p&gt;Alternatively, refresh tokens should be rotated by the authorization server. Refresh token rotation means every time the authorization server receives a request to refresh the access token for a user, a new refresh token is also issued, and the previous token is invalidated.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Access tokens should grant the minimum privileges needed
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foutoqfi1d5fqvoxop1wb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foutoqfi1d5fqvoxop1wb.png" alt=" " width="200" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Access tokens provide authorization to access protected resources. Overloading access tokens with more permissions than needed increases risk. Access tokens should grant the bare minimum permissions.&lt;/p&gt;

&lt;p&gt;Restrict access token use to a specific API (or at the most, a small set of APIs). An access token uses an &lt;code&gt;aud&lt;/code&gt; (audience) parameter to store the ID of the API (or resource server) it’s intended for. Any resource server not listed in the &lt;code&gt;aud&lt;/code&gt; must reject the token and deny access.&lt;/p&gt;

&lt;p&gt;Once an API verifies it’s the intended audience of the access token, it still needs to restrict access to specific resources or actions. The token may contain a &lt;a href="https://www.rfc-editor.org/rfc/rfc6749.html#page-23" rel="noopener noreferrer"&gt;&lt;code&gt;scope&lt;/code&gt; parameter&lt;/a&gt; or &lt;a href="https://www.rfc-editor.org/rfc/rfc9396.html" rel="noopener noreferrer"&gt;&lt;code&gt;authorization_details&lt;/code&gt;&lt;/a&gt; that tell the API what to allow. For every request, the API must verify that the token does indeed grant the requested access.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Don’t use user credentials to obtain access tokens
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc6749.html#page-9" rel="noopener noreferrer"&gt;Resource Owner Password Credentials (ROPC)&lt;/a&gt; is an OAuth 2.0 grant type that uses user credentials (such as username and password) for authorization to obtain an access token. This must not be used. Considering the other best practices above, it may already be clear why this is now prohibited. ROPC insecurely exposes the user’s credentials to the client. It has an increased attack surface and isn’t designed to work with multi-factor authentication. Since ROPC is bound to a specific web origin, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API" rel="noopener noreferrer"&gt;WebCrypto&lt;/a&gt; and &lt;a href="https://fusionauth.io/articles/authentication/webauthn" rel="noopener noreferrer"&gt;WebAuthn&lt;/a&gt; may be impossible to use with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Authorization servers should enforce client authentication
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5cbfak482rq2dtb3fipi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5cbfak482rq2dtb3fipi.png" alt="authorization server" width="200" height="231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This best practice is more relevant to authorization server providers than app developers, but it provides important context. Client authentication is when an authorization provider verifies the app is who it claims to be. Authorization servers should issue and register confidential client credentials to do this.&lt;/p&gt;

&lt;p&gt;The authorization server should use asymmetric cryptography such as &lt;a href="https://www.rfc-editor.org/rfc/rfc8705.html" rel="noopener noreferrer"&gt;mTLS for OAuth 2.0&lt;/a&gt; or &lt;a href="https://www.rfc-editor.org/rfc/rfc7523.html" rel="noopener noreferrer"&gt;Signed JSON Web Token&lt;/a&gt; (Private Key JWT) to verify the identity of an app requesting authorization. JWT asymmetric cryptography means a private key is used to encrypt data and a different, public key is needed to decrypt it. This way, authorization servers don’t need to store sensitive symmetric keys (which can both encrypt and decrypt data).&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Other recommendations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The authorization server must &lt;em&gt;not&lt;/em&gt; allow &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" rel="noopener noreferrer"&gt;Cross-Origin Resource Sharing (CORS)&lt;/a&gt; at its &lt;a href="https://datatracker.ietf.org/doc/html/rfc6749#section-3.1" rel="noopener noreferrer"&gt;authorization endpoint&lt;/a&gt; since the client redirects the browser to this endpoint rather than accessing it directly.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.rfc-editor.org/rfc/rfc8414.html" rel="noopener noreferrer"&gt;OAuth Authorization Server Metadata&lt;/a&gt; can help improve security. Authorization servers should publish metadata and clients should use this metadata for configuration.

&lt;ul&gt;
&lt;li&gt;This ensures that security features and new OAuth features can be enabled automatically by software libraries.&lt;/li&gt;
&lt;li&gt;Metadata reduces misconfiguration.&lt;/li&gt;
&lt;li&gt;Metadata can help cryptographic key rotation.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Authorization servers should not allow clients to influence their own &lt;code&gt;client_id&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;End-to-end TLS (Transport Layer Security) between the client and API is recommended.&lt;/li&gt;

&lt;li&gt;Unencrypted network connections (&lt;code&gt;HTTP&lt;/code&gt;) should not be allowed when transmitting authorization responses (except on native clients that use loopback interface redirection).&lt;/li&gt;

&lt;li&gt;If the authorization response is sent with in-browser communication like &lt;code&gt;postMessage&lt;/code&gt; instead of &lt;code&gt;HTTP&lt;/code&gt; redirects, both the sender and receiver must be verified.&lt;/li&gt;

&lt;li&gt;Endpoints &lt;em&gt;directly accessed&lt;/em&gt; by clients may support CORS (i.e., without browser redirection), such as the token endpoint, metadata endpoint, etc.&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Attacker model, attacks, and mitigations
&lt;/h2&gt;

&lt;p&gt;RFC 9700 Best Current Practice for OAuth 2.0 Security also includes an &lt;a href="https://www.rfc-editor.org/rfc/rfc9700.html#name-the-updated-oauth-20-attack" rel="noopener noreferrer"&gt;updated OAuth 2.0 attacker model&lt;/a&gt; and descriptions of &lt;a href="https://www.rfc-editor.org/rfc/rfc9700.html#name-attacks-and-mitigations" rel="noopener noreferrer"&gt;security attacks and guidance for their mitigation&lt;/a&gt;. Though this article doesn’t cover these parts of the specification in detail, some attacks and mitigations are briefly covered with the best practices above. To learn more about the attacker model, attacks, and mitigations, please see the specification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope this developer’s overview of OAuth 2.0 Best Current Practice was useful! If you have any questions or just want to chat, please reach out to me on &lt;a href="https://linkedin.com/in/kimmaida" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://bsky.app/profile/maida.kim" rel="noopener noreferrer"&gt;Bluesky&lt;/a&gt;, or &lt;a href="https://x.com/KimMaida" rel="noopener noreferrer"&gt;X&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>oauth</category>
      <category>authentication</category>
    </item>
    <item>
      <title>How to Drive Developer Growth and Engagement</title>
      <dc:creator>Kim Maida</dc:creator>
      <pubDate>Wed, 19 Oct 2022 20:13:40 +0000</pubDate>
      <link>https://dev.to/kimmaida/how-to-drive-developer-growth-and-engagement-4nm9</link>
      <guid>https://dev.to/kimmaida/how-to-drive-developer-growth-and-engagement-4nm9</guid>
      <description>&lt;p&gt;To effectively drive sustainable developer growth and engagement for products that serve developers, I created the Developer Empowerment flywheel. When connecting with developer audiences on behalf of an organization, driving developer growth and engagement needs to be cross-functional, measurable, and scalable.&lt;/p&gt;

&lt;p&gt;My Developer Empowerment flywheel looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rgijk4tssyuy5cpe49k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rgijk4tssyuy5cpe49k.png" alt="Developer Empowerment flywheel by Kim Maida" width="800" height="835"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspire
&lt;/h2&gt;

&lt;p&gt;We want to inspire developers in the community in a variety of ways, including but not limited to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ideas&lt;/strong&gt; – Sharing inspiration on what the product’s capabilities are and how to begin. We want to start small: have fun and share basic examples with a low barrier to entry. Showcase possibilities and get people to an “aha!” moment as early as possible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use cases&lt;/strong&gt; – Show how building with the product helps in a practical sense. How does developing with our product solve pain points, enable new capabilities, and provide features that developers want to take advantage of in the real world?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Showcases&lt;/strong&gt; – Highlight the really cool, powerful, and / or unique projects that developers have built.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Opportunities&lt;/strong&gt; – Inspire developers to explore, experiment, and think much more broadly about how they can build awesome projects and accomplish things that they haven’t been able to accomplish previously, without our product.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Educate
&lt;/h2&gt;

&lt;p&gt;Next we want to provide valuable learning resources to educate developers on how to build efficiently and effectively with our product.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Documentation&lt;/strong&gt; – Provide thorough, easy-to-follow documentation with an exceptional developer experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tutorials&lt;/strong&gt; – Create and share tutorials, quick starts, blog posts and other learning content on a variety of mediums including written, video, interactive, and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Demos&lt;/strong&gt; – Share practical demos with real-world applicability; go beyond Hello World to provide value by showing developers how to build things that are practical and useful.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Presentations&lt;/strong&gt; – Talk about how to think about architecture, design patterns, principles, and best practices; provoke thought and be available to answer questions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workshops&lt;/strong&gt; – Dig deeper with more involved guided learning and teach interactively. Workshops are high value because of the depth of commitment involved.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Education also goes beyond technical content: it’s also about helping developers to think about strategic organizational problem solving, hacking productivity, and builder best practices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Activate
&lt;/h2&gt;

&lt;p&gt;Next we want to activate developers to start building and actively touching the product. This can take a few different shapes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Create New&lt;/strong&gt; – Sign up and take an action (install an SDK, create an app, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit Code&lt;/strong&gt; – Start writing code (commit code to a repository, make an API call, deploy to an environment, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subscribe&lt;/strong&gt; – Subscribe to newsletters, course platforms, podcasts, YouTube channels, Twitch channels, etc. Commit to learning more on a regular basis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Join Community&lt;/strong&gt; – Join a product-related developer community or user group.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reach Out&lt;/strong&gt; – Activate developers to reach out to product advocates to have conversations, find out more, and ask questions as they’re getting started.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Engage
&lt;/h2&gt;

&lt;p&gt;Once we’ve activated developers to get involved with the product, we want to engage with the developer community.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Discussions&lt;/strong&gt; – Engage developer users to participate in chats or discussions, such as communities, forums, and social platforms like Reddit, StackOverflow, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Program Participation&lt;/strong&gt; – Engage developers to actively participate in activities like hackathons or longer-running developer initiatives like 100 Days of Code challenges; engage developers to join and actively contribute in developer community programs like ambassador or expert or certification&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provide Feedback&lt;/strong&gt; – Encourage developers in the community to engage in conversations providing value product and / or developer experience feedback.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask Questions&lt;/strong&gt; – Engage with product advocates to ask questions that aren’t in the docs and show active interest in learning more and going deeper.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Empower
&lt;/h2&gt;

&lt;p&gt;Finally, we want to empower builders to inspire other developers and continue to perpetuate the Developer Empowerment cycle.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Support&lt;/strong&gt; – We want to provide support and resources to help developers teach others what they’ve learned.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable&lt;/strong&gt; – Let’s provide high-value opportunities for developers to learn from and work with advocacy teams at the organization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Promote&lt;/strong&gt; – We should shine a spotlight on work developers in the community have done and promote resources they’ve created.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advocate&lt;/strong&gt; – We should empower builders to become advocates themselves and teach others.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Empowerment can happen through a variety of different avenues. We can create experts and ambassadors programs, facilitate and support external community meetups, and put on developer conferences wherein we invite and highlight community speakers and contributors. We can also partner with community experts and content creators. By empowering developers who build with our products, we foster the continuation of the developer empowerment cycle.&lt;/p&gt;




&lt;h2&gt;
  
  
  People
&lt;/h2&gt;

&lt;p&gt;Who are the participants and contributors in the Developer Empowerment flywheel?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Developer audience&lt;/strong&gt; – Developers in the community with the potential to use the product are key to target in the Inspire and Educate phases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Builders&lt;/strong&gt; – Builders are developers who currently are in the process of learning to develop with the product, or are actively developing with it. This could include members of the wider developer ecosystem, developer customers, or internal engineers who work on the product itself. We want to ensure we are educating, activating, and engaging with Builders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Champions&lt;/strong&gt; – Champions are developers who actively advocate for the product in the community. Developer champions create educational content, provide product feedback, participate and contribute to developer community programs, and / or share the work they’ve done with the product and encourage others to use the product as well. Champions are developers who we want to empower so they can contribute to the flywheel by inspiring and educating more of the developer audience.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Cross-Functional Developer Growth and Engagement
&lt;/h2&gt;

&lt;p&gt;Developer Relations is uniquely positioned to be capable of supporting, collaborating with, and facilitating the work done by almost every other department in an organization. Here are a few examples of cross-functional work and support that can be done in the Developer Empowerment flywheel fostering developer growth and engagement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Product
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Collect and execute product feedback&lt;/li&gt;
&lt;li&gt;Collect and execute developer experience feedback&lt;/li&gt;
&lt;li&gt;APIs and SDKs adoption, usage, and engagement&lt;/li&gt;
&lt;li&gt;Documentation feedback, improvements, and content contribution&lt;/li&gt;
&lt;li&gt;Guides, tutorials, and quick start content creation, promotion, and experimentation&lt;/li&gt;
&lt;li&gt;Developer tooling&lt;/li&gt;
&lt;li&gt;High-value feature identification on product roadmap in response to community insights and feedback&lt;/li&gt;
&lt;li&gt;Beta-testing, early access, and Developer Advisory groups&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Partnerships
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Partner-developed integrations&lt;/li&gt;
&lt;li&gt;Co-marketing

&lt;ul&gt;
&lt;li&gt;Technical case studies and demos&lt;/li&gt;
&lt;li&gt;Partner showcase&lt;/li&gt;
&lt;li&gt;Webinars and events&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Partner developer training and enablement&lt;/li&gt;

&lt;li&gt;Developer partner programs

&lt;ul&gt;
&lt;li&gt;Product insiders&lt;/li&gt;
&lt;li&gt;Developer certification&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Developer Marketing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Developer Content

&lt;ul&gt;
&lt;li&gt;Blog posts&lt;/li&gt;
&lt;li&gt;Demos and sample applications&lt;/li&gt;
&lt;li&gt;Quick starts and guides&lt;/li&gt;
&lt;li&gt;Videos, livestreams, office hours&lt;/li&gt;
&lt;li&gt;Live events, workshops, trainings, launch events&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Developer community

&lt;ul&gt;
&lt;li&gt;Engage in conversations with developers (live and async)&lt;/li&gt;
&lt;li&gt;Promotion of developer projects and contributions&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Developer programs

&lt;ul&gt;
&lt;li&gt;Developer Experts / Champions / Ambassadors&lt;/li&gt;
&lt;li&gt;Developer certification program&lt;/li&gt;
&lt;li&gt;Technical training&lt;/li&gt;
&lt;li&gt;Advocacy empowerment&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Additional Cross-Functional Opportunities
&lt;/h3&gt;

&lt;p&gt;In addition to the above, there are also many more opportunities for cross-functional work throughout the flywheel. Developer growth and engagement can work with Field and Sales teams to target specific regions or verticals, tilling and fertilizing the soil so Sales can plant seeds.&lt;/p&gt;

&lt;p&gt;We can also work alongside Customer Success to “open source” common support questions and answers to create public FAQs, rotate forum staff, and create new resources while also performing ticket deflection.&lt;/p&gt;

&lt;p&gt;Developer growth and engagement and developer relations also have opportunities to partner closely with Architecture or the Office of the CTO to ensure growth and engagement teams are consistently providing highest quality best practices and the most accurate information and resources to the developer community.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Measure Developer Growth and Engagement
&lt;/h2&gt;

&lt;p&gt;The Developer Empowerment flywheel is measurable in a number of different ways.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trusted Metrics
&lt;/h3&gt;

&lt;p&gt;Trusted metrics directly measure developer growth and engagement and conversion. Personally, I like to focus on percent of month over month growth over time rather than on specific “magic numbers.” Examples of trusted metrics include (but are not limited to):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Growth in Monthly Active Users&lt;/li&gt;
&lt;li&gt;Growth in new tenants / apps / instances created&lt;/li&gt;
&lt;li&gt;Growth in projects deployed&lt;/li&gt;
&lt;li&gt;Growth in projects publicly distributed in marketplaces&lt;/li&gt;
&lt;li&gt;Subscriber growth (developer newsletters, courses, content channels such as Twitch, YouTube, etc.)&lt;/li&gt;
&lt;li&gt;Growth in monthly active participants in developer programs&lt;/li&gt;
&lt;li&gt;DevRel Qualified Leads&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Insight Metrics
&lt;/h3&gt;

&lt;p&gt;Insight metrics are helpful and informative, but should not be used to measure success in a strict sense — success should be measured through trusted metrics. These metrics help us to identify trends, patterns, and general awareness.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Documentation traffic growth&lt;/li&gt;
&lt;li&gt;API and SDK usage&lt;/li&gt;
&lt;li&gt;New content developed&lt;/li&gt;
&lt;li&gt;Number of people reached through content, presentations, sponsorships, etc.&lt;/li&gt;
&lt;li&gt;GitHub metrics&lt;/li&gt;
&lt;li&gt;Package installation metrics&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Performance Indicators
&lt;/h3&gt;

&lt;p&gt;Key Performance Indicators (or KPIs) help us understand how we’re doing, growing, and making progress. KPIs should be used in conjunction with trusted metrics. Similarly, setting KPI goals that are measured by percentage growth month over month helps teams to focus on performing scalable efforts rather than fixating on a single goal number each month or quarter. When goals are set to grow over time, contributors concentrate their strategies, tactics, and overall efforts on initiatives that continue to grow exponentially to continually generate outcomes, rather than starting and concluding with one outcome.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Growth in content and documentation traffic&lt;/li&gt;
&lt;li&gt;Improvements implemented as a result of developer feedback

&lt;ul&gt;
&lt;li&gt;Developer experience feedback implemented&lt;/li&gt;
&lt;li&gt;Developer product feedback implemented&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Growth in people reached through trainings, workshops, presentations&lt;/li&gt;

&lt;li&gt;Developer program membership growth

&lt;ul&gt;
&lt;li&gt;Developer community contributions&lt;/li&gt;
&lt;li&gt;Developers certified&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Developer campaign engagement&lt;/li&gt;

&lt;li&gt;Developers reached through partnership engagements&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Scalable Developer Growth and Engagement
&lt;/h2&gt;

&lt;p&gt;One of the most important key features of the Developer Empowerment flywheel is that it’s scalable. Scalability is vital when we are driving sustainable developer growth and engagement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Company Developer Engagement and Advocacy
&lt;/h3&gt;

&lt;p&gt;Within the organization, we ensure that we have developer growth and engagement as well as developer advocacy actively working to empower developer users and community. This includes making sure that we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create scalable resources, content, programs, and initiatives&lt;/li&gt;
&lt;li&gt;Empower developers in the community by teaching, enabling, and supporting&lt;/li&gt;
&lt;li&gt;Have candid conversations and answer questions&lt;/li&gt;
&lt;li&gt;Collect and act on feedback to implement actionable changes and improvements&lt;/li&gt;
&lt;li&gt;Advocate on behalf of the developer users to the company&lt;/li&gt;
&lt;li&gt;Promote and share work and accomplishments from the developer community&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Developer Community
&lt;/h3&gt;

&lt;p&gt;Empower and engage with the developer community to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use and share helpful resources&lt;/li&gt;
&lt;li&gt;Participate in learning campaigns, code challenges, hackathons, courses, etc.&lt;/li&gt;
&lt;li&gt;Provide product and developer experience feedback&lt;/li&gt;
&lt;li&gt;Build amazing things&lt;/li&gt;
&lt;li&gt;Subscribe to content (newsletters, content channels, forums)&lt;/li&gt;
&lt;li&gt;Share accomplishments&lt;/li&gt;
&lt;li&gt;Join developer programs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Sustainable Developer Empowerment
&lt;/h3&gt;

&lt;p&gt;Sustainable developer empowerment means that we are continuously ensuring that we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support developers in the community

&lt;ul&gt;
&lt;li&gt;Teach beginner, intermediate, and advanced developers&lt;/li&gt;
&lt;li&gt;Solve problems&lt;/li&gt;
&lt;li&gt;Advocate for the developer experience&lt;/li&gt;
&lt;li&gt;Create a productive feedback cycle&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Empower developers in the community to inspire and educate others

&lt;ul&gt;
&lt;li&gt;Share how to teach&lt;/li&gt;
&lt;li&gt;Promote the work and accomplishments of developers in the community&lt;/li&gt;
&lt;li&gt;Write the “missing manual” by identifying questions and pain points from active developers&lt;/li&gt;
&lt;li&gt;Spotlight great work&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Empower developer employees within the company

&lt;ul&gt;
&lt;li&gt;Share what they’re working on&lt;/li&gt;
&lt;li&gt;Promote engineering and content work&lt;/li&gt;
&lt;li&gt;Support internal employee advocacy&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Organizations that care deeply about developer products, developer experience, and developer users can take advantage of the Developer Empowerment flywheel to continually increase their developer growth and engagement.&lt;/p&gt;




&lt;p&gt;If you would like to use it in your organization collateral, the &lt;a href="https://maida.kim/wp-content/uploads/2022/10/KimMaida-developer-empowerment-flywheel.png" rel="noopener noreferrer"&gt;Developer Empowerment flywheel graphic can be downloaded here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devrel</category>
      <category>devex</category>
      <category>growth</category>
    </item>
    <item>
      <title>How to Connect With Your Developer Audience</title>
      <dc:creator>Kim Maida</dc:creator>
      <pubDate>Tue, 26 Apr 2022 12:05:42 +0000</pubDate>
      <link>https://dev.to/kimmaida/how-to-connect-with-your-developer-audience-4fa6</link>
      <guid>https://dev.to/kimmaida/how-to-connect-with-your-developer-audience-4fa6</guid>
      <description>&lt;p&gt;If your organization provides any kind of technology or service that is consumed by developers, you’ve likely asked “How do we build our developer audience?” In &lt;a href="https://dev.to/kimmaida/which-department-does-devrel-belong-in-3om"&gt;Which Department Does DevRel Belong In&lt;/a&gt;? I mentioned that it’s a myth that “developers hate marketing.” Let’s dig a little deeper into the developer audience and what we (I am a developer myself) are looking for when we evaluate products, technologies, and even the very companies that market to us. How can Developer Relations teams form a positive and lasting connection with their developer audience?&lt;/p&gt;

&lt;h2&gt;
  
  
  What Does Your Developer Audience Want?
&lt;/h2&gt;

&lt;p&gt;The first step in understanding the developer audience is identifying what developers want. And this shouldn’t be surprising: developers want the same things everyone else wants. Developers want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High quality tools, products, and services&lt;/li&gt;
&lt;li&gt;To be able to trust the brands they support&lt;/li&gt;
&lt;li&gt;Their lives and work to be more seamless and efficient&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What are the characteristics of developers as an audience for your products and services?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers are technologically savvy and have a keen understanding of the digital space&lt;/li&gt;
&lt;li&gt;By virtue of their profession, developers have highly developed critical thinking skills&lt;/li&gt;
&lt;li&gt;Most developers are sensitive to and repulsed by dark marketing tactics&lt;/li&gt;
&lt;li&gt;Developers are good at spotting BS&lt;/li&gt;
&lt;li&gt;Developers can also be somewhat unforgiving — get on someone’s bad side once, and you may very well lose them forever&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Developer Relations is About Building Great Relationships
&lt;/h2&gt;

&lt;p&gt;Developer Relations is about &lt;em&gt;relationships&lt;/em&gt;. This is no surprise. But what are the foundations of great relationships that thrive and endure?&lt;/p&gt;

&lt;p&gt;There are several things we should focus on in order to connect with developer communities and form positive relationships with developers. This can be boiled down in a straightforward sequence:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. We Act With Integrity and Empathy
&lt;/h2&gt;

&lt;p&gt;Developer Relations does not practice lip service or sycophancy. We don’t flatter or agree with influential people or companies just to gain an advantage from them; we don’t butter people up or shine apples.&lt;/p&gt;

&lt;p&gt;In DevRel, we don’t just say what people want to hear. We don’t support something if we can’t back it up with actions. Developer Relations is about relationships, and great relationships are built on trust. Developer Relations aims to have a great relationship with developer users, and to do this, DevRel’s core philosophy and communications must have integrity and empathy, and this fosters respect.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solve Problems, Have Conversations, Be Open to Criticism
&lt;/h3&gt;

&lt;p&gt;We listen. This means listening to the good, and to the bad. In DevRel, we listen to what people have to say without rushing headlong to provide default solutions. We have conversations instead of Q&amp;amp;As and take the time and care to understand our developer users and their challenges and needs. Emotional intelligence and empathy are key qualities that anyone working in Developer Relations should have in abundance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Different Strokes for Different Folks
&lt;/h3&gt;

&lt;p&gt;We recommend what we honestly feel works best for the user, not what serves only our own interests. Tech is not one-size-fits-all. We don’t sell a user on a tool that isn’t the right fit for them or their needs. Recommending the least-best — or even second-best — solution (if we know the best solution is elsewhere) will only backfire and result in negative sentiment overall. We aren’t selling or shilling; we’re forging relationships.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep Promises
&lt;/h3&gt;

&lt;p&gt;We are honest and realistic about options and next steps, and then we back up what we say with actions. When we make a recommendation or a promise, we stand by our word and take responsibility for the outcomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Build Trust and Respect
&lt;/h2&gt;

&lt;p&gt;When we act with integrity, we foster trust and build respect with our developer audience. Developers tolerate (and occasionally even enjoy) sales and marketing, but if they sense you might be disingenuous, you risk losing them forever.&lt;/p&gt;

&lt;p&gt;We build trust and respect by acting with integrity, solving problems, and providing honest discourse and high-quality resources. This is true for products and also for the organizations that provide the products. In many cases, a company’s reputation can become entwined with the level of respect a developer has for the service or software being provided.&lt;/p&gt;

&lt;p&gt;To continue to build trust and respect, Developer Relations teams should instill quality and integrity in all of their work. This includes conversations and communications, but also presentations, blog and video content, event participation, documentation, GitHub interactions, and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Inspire Loyalty and Confidence
&lt;/h2&gt;

&lt;p&gt;Acting with integrity and building trust and respect inspires loyalty and confidence in products and in the organization providing those products. In Developer Relations, we are working to satisfy and serve our developer product users. But that’s not all: we’re also brand ambassadors representing an organization to a developer audience.&lt;/p&gt;

&lt;p&gt;A company whose products are represented with integrity, thoughtfulness, and high quality resources inspires confidence in its users. Trust and confidence inspires loyalty, and your developer audience will come along with you and continue to support your products and organization as long as you both serve their needs and prove worthy of their respect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect With Your Developer Audience
&lt;/h2&gt;

&lt;p&gt;To really connect with your developer audience, you don’t need to have the most followers on Twitter, be the most famous speaker, have the shiniest reputation, work at the most prestigious company, or even have the most popular product. You need to act with integrity and empathy, and provide high quality resources and insights. This builds trust and respect in your developer community, and inspires loyalty and confidence with your developer audience.&lt;/p&gt;

</description>
      <category>devrel</category>
      <category>developers</category>
    </item>
    <item>
      <title>Which Department Does Developer Relations Belong In?</title>
      <dc:creator>Kim Maida</dc:creator>
      <pubDate>Sun, 11 Jul 2021 18:44:13 +0000</pubDate>
      <link>https://dev.to/kimmaida/which-department-does-devrel-belong-in-3om</link>
      <guid>https://dev.to/kimmaida/which-department-does-devrel-belong-in-3om</guid>
      <description>&lt;p&gt;The battle over which department &lt;a href="https://dev.to/kimmaida/the-developer-relations-explainer-431o"&gt;Developer Relations&lt;/a&gt; belongs in continues to be long and ongoing.&lt;/p&gt;

&lt;p&gt;Does DevRel belong in Product? Marketing? Engineering? Any of the above? None of the above?&lt;/p&gt;

&lt;p&gt;Discussions — and arguments — over where DevRel should align in an organization often become heated and passionate. Many practitioners have very strong feelings about this, occasionally holding views that are not aligned with where their organization's executive leadership believes DevRel should report.&lt;/p&gt;

&lt;p&gt;The thing is, the answer here is complex and nuanced. Developer Relations is so many disciplines combined. DevRel is about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connecting with developer users and audiences&lt;/li&gt;
&lt;li&gt;Cultivating, growing, and nurturing developer communities&lt;/li&gt;
&lt;li&gt;Advocating on behalf of developers to make better products with a great developer experience&lt;/li&gt;
&lt;li&gt;Advocating on behalf of the organization to bring products to more developer users&lt;/li&gt;
&lt;li&gt;Understanding the product on a deep, technical level and providing education, resources, and support to developers&lt;/li&gt;
&lt;li&gt;Engineering demos, samples, real world repos, code tutorials, etc.&lt;/li&gt;
&lt;li&gt;...and so, so much more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These goals and responsibilities fit into several different "segments" of a typical tech organization. DevRel also &lt;em&gt;needs&lt;/em&gt; resources, cooperation, and collaboration across many teams and departments in order to be successful. &lt;/p&gt;

&lt;p&gt;So the question repeatedly arises: where does Developer Relations belong in an organization? &lt;/p&gt;

&lt;p&gt;I have worked in Developer Relations at four different companies. I have had countless conversations with peers in the industry regarding org structure, and where DevRel belongs in order to be successful and effective. In these conversations over the years, the often-repeated stance I kept hearing was that &lt;strong&gt;"DevRel shouldn't be in Marketing."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have heard this dozens of times. I have said it &lt;em&gt;myself&lt;/em&gt; in the past.&lt;/p&gt;

&lt;p&gt;But why?&lt;/p&gt;

&lt;p&gt;Why do we keep insisting that DevRel doesn't belong in Marketing? And why then, is DevRel &lt;em&gt;very often in Marketing anyway&lt;/em&gt;?&lt;/p&gt;

&lt;h2&gt;
  
  
  Myth: "Leadership Doesn't Understand DevRel"
&lt;/h2&gt;

&lt;p&gt;Every company I've done DevRel at has had DevRel in the Marketing org. Why would companies do this if it was not appropriate? As practitioners of Developer Relations, do we actually believe that our employers would put so much money, care, and sheer effort into hiring DevRel teams and providing them with substantial financial resources if they &lt;em&gt;didn't&lt;/em&gt; understand the reasons behind having DevRel in the first place?&lt;/p&gt;

&lt;p&gt;For years, we've claimed that DevRel is such a new discipline, executive leadership doesn't &lt;em&gt;understand&lt;/em&gt; the true purpose of DevRel. We've insisted that our leadership thinks DevRel is about pipeline, or lead gen, and doesn't &lt;em&gt;get&lt;/em&gt; that it's &lt;em&gt;something else&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;But c'mon now. DevRel is no longer a new discipline in tech. Company leaders are not hiring DevRel teams without understanding what they mean and what their goals are. They aren't doing it because their competitors have DevRel teams. Hundreds of thousands — even millions — of dollars are poured into DevRel teams. Org leaders do &lt;em&gt;not&lt;/em&gt; do that carelessly. They do not do that if they don't understand what they're doing it &lt;em&gt;for&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It's time to give our executive leadership more credit than that. And it's an exciting time: DevRel has matured to the point now that there are executive DevRel roles. &lt;strong&gt;Developer Relations, as a key discipline, has earned its place at the leadership table.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The old argument of "my org's leadership doesn't understand DevRel, that's why they put us in Marketing" no longer stands up under scrutiny. It is still true in some companies, but I would strongly encourage folks who are looking for DevRel roles to vet potential employers carefully during an interview process to determine if the greater understanding of DevRel is shared by leadership. (Just ask "what does DevRel mean to your company?" and you'll get your answer. If there's not alignment between the answer and your fundamental philosophy, it might be a sign to pass and look elsewhere.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Myth: "DevRel Isn't About Making Money"
&lt;/h2&gt;

&lt;p&gt;Weeelll...&lt;/p&gt;

&lt;p&gt;That's untrue. It's untrue because (unless you work for a nonprofit) &lt;em&gt;every team at a tech product company exists to make money&lt;/em&gt;. Engineering builds products to make money. Design designs products to make money. Marketing promotes products to make money. Sales sells products to make money. Investors invest in startups to make money. Companies raise funding to eventually become profitable (a.k.a. make money). And yes, DevRel educates and shares and helps to — you guessed it — make money.&lt;/p&gt;

&lt;p&gt;In DevRel, we sometimes like to say that we aren't "selling" the product. But that isn't entirely accurate. When we evangelize a technology — even an open source one — we are selling people on the &lt;em&gt;idea that a technology or product can help them or make their work better / easier / faster / etc&lt;/em&gt;. While that isn't Sales in the classic sense, it &lt;em&gt;is&lt;/em&gt; about encouraging people to choose to use something in order to improve their lives in some way.&lt;/p&gt;

&lt;p&gt;And that is the crux of &lt;a href="https://blog.taboola.com/effectively-top-funnel-marketing/#:~:text=Top%20of%20the%20funnel%20marketing%20refers%20to%20the%20first%20stage,hopefully%2C%20eventually%2C%20become%20customers." rel="noopener noreferrer"&gt;Top of Funnel marketing&lt;/a&gt;. We want to increase brand awareness. We hope the developers we reach will choose to use our products. We hope they have a great experience with us and want to &lt;em&gt;continue&lt;/em&gt; to be users of our products. And we hope that, at some point, they will get enough benefit and value out of the product that they consider it very worth paying for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Myth: "Developers Hate Marketing"
&lt;/h2&gt;

&lt;p&gt;This blanket statement is not true either. A more accurate statement might be: "Developers are good at detecting BS." As we should be!&lt;/p&gt;

&lt;p&gt;We developers are consumers too. We consume products, watch ads (okay, mostly when forced to), glance at sponsored content, read signs in shop windows, and check out sponsor halls at conferences.&lt;/p&gt;

&lt;p&gt;I — as a human being and &lt;em&gt;also&lt;/em&gt; as a developer — &lt;em&gt;want&lt;/em&gt; to be told about products and technology that can make my life better. I &lt;em&gt;want&lt;/em&gt; to be marketed tech products that are a pleasure to use, increase efficiency, and help me do my job. I encourage you: do your best to market to my interests! I'm a tough crowd, but I welcome it. And I'm more than happy to pay for your product — &lt;em&gt;if it's worth it&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The notion that "developers hate marketing" is an oversimplification. The misconception that marketing is inherently &lt;em&gt;insidious&lt;/em&gt; or &lt;em&gt;disingenuous&lt;/em&gt; is where this idea goes seriously astray; and that's why DevRel's role in Developer Marketing is so pivotal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer Relations 💙 Developer Marketing at Developer-First Companies
&lt;/h2&gt;

&lt;p&gt;Whether your DevRel team reports to Product, Engineering, Marketing, directly to the founders, or elsewhere in the organization, DevRel is — at its core — Developer Marketing.&lt;/p&gt;

&lt;p&gt;This is a &lt;em&gt;good&lt;/em&gt; thing. And it's time for us to &lt;em&gt;recognize and acknowledge&lt;/em&gt; that it's a good thing.&lt;/p&gt;

&lt;p&gt;At developer-first product companies, Marketing is a great place for Developer Relations. I want to make this distinction very clear though: when a company’s primary objective and business model is centered on creating software or tools for developers, the understanding of Developer Relations comes from the top down. &lt;strong&gt;Open Source or developer software companies have a prime directive that focuses on developer satisfaction, adoption, and happiness.&lt;/strong&gt; At these companies, DevRel being in Marketing makes sense.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;em&gt;At companies in other product sectors, it may make much&lt;/em&gt; less &lt;em&gt;sense for DevRel to be in Marketing. If your company sells a consumer product, B2B, or B2E — and you also provide APIs, etc., then DevRel may serve much better in Engineering or Product.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;DevRel in Marketing at developer-first companies can work well for several reasons:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Marketing has a deep-rooted, cooperative relationship with Product.&lt;/strong&gt; Espoused in the discipline of Product Marketing, Marketing as an organizational powerhouse has an intimate but also &lt;em&gt;holistic&lt;/em&gt; knowledge of what's going on in Product and Engineering: what features are being developed, what's happening when, who the primary users would be, what user research is being done, how should the product be presented to the market, etc. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Marketing has budget for the types of things DevRel teams do.&lt;/strong&gt; DevRel is expensive! Sponsorships, swag, airfare, hotels, streaming, recording, production, running programs and campaigns, etc. cost &lt;em&gt;a lot of money&lt;/em&gt;. Marketing is generally allocated significant budgets for &lt;em&gt;exactly&lt;/em&gt; these types of things. If DevRel is in Engineering or Product, DevRel teams &lt;em&gt;may&lt;/em&gt; struggle with obtaining enough budget for things like big sponsorships, sweepstakes prizes, etc. since DevRel activities may not be well incorporated into the bottom line for how the department's performance is typically measured (but of course, YMMV).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Marketing is data-driven.&lt;/strong&gt; DevRel is notoriously "hard to measure" — but is it really? Marketing organizations are data-driven, and operate with growth in mind. Having ready access to metrics like attribution, website and blog traffic, npm traffic, signups, trials, HubSpot, Twitter, YouTube, Twitch, competitive analytics, etc. can be quite beneficial for plotting a course for increasing DevRel performance, engagement, and adoption. Working alongside Marketing teams like Data, Brand, and Growth can make a huge difference in enabling DevRel to gather, predict, and respond to a broad spectrum of data regarding how a company interacts with users and potential users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Marketing operates with a growth mindset, and thrives on experimentation.&lt;/strong&gt; Experimentation and testing different strategies and tactics is par for the course for a Marketing organization. And experimentation is a crucial component of DevRel. Testing different DevRel strategies, programs, and campaigns is a mode of operations that Marketing supports, encourages, and has the means to execute quickly. Pivoting on a dime won't shock Marketing leadership, and unsuccessful experiments result in good learning experiences, not reprimand or backlash.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Marketing owns the strategy around how a product is delivered to an audience.&lt;/strong&gt; Different types of products require different GTM (Go To Market) strategies. Open source software release? DevRel can be out ahead of that: connecting with OSS devs, running interference on GitHub, holding demo livestreams and office hours, doing talks at events, and more. Big commercial release? Maybe DevRel supports Product Marketing by hosting technical demos, sharing access to new features with community champions, arranging impactful event sponsorships, and forwarding booth inquiries to Sales. DevRel is an integral part of GTM, and being in Marketing enables DevRel teams to have ownership over their role and responsibilities when product releases go public. Some DevRel teams in Marketing wrote and own the entire GTM strategy and process for OSS launches.&lt;/p&gt;

&lt;p&gt;These are just a few examples of how DevRel fits well into a Marketing org. There are many more (e.g., working closely with Content Marketing, Brand, Growth, Social Media, Partners, Marketing Engineering, Data, Demand Generation... the list goes on).&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer Marketing Core Philosophy
&lt;/h2&gt;

&lt;p&gt;My core philosophy around Developer Marketing is concerned with three primary tenets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be Genuine&lt;/li&gt;
&lt;li&gt;Build Trust&lt;/li&gt;
&lt;li&gt;Deliver Value&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Developers want their work to go smoothly, be efficient, and be interesting; there’s a nuanced difference between this and wanting things to simply be "easy." Developers are interested in technology that enables these things, and allows them to do work that they are then proud of and feel good about.&lt;/p&gt;

&lt;p&gt;Being genuine and building trust are of tantamount importance at an ethical level. Companies that focus on this are going to be more successful. Developer Relations is the piece of the organization that most strongly embodies this, and cultivates relationships built on clarity and trust with the developer community.&lt;/p&gt;

&lt;p&gt;Then put your money where your mouth is: Developer Relations is about &lt;em&gt;delivering value&lt;/em&gt; to developers. Back up words with actions: share knowledge, take feedback, make things happen as a result.&lt;/p&gt;

&lt;p&gt;This is what marketing to developers is about: are we offering something that is genuinely useful? Is it helpful? Does it improve life for developers, and for their teams? Does it have a great developer user experience? If yes, developers are going to be open to trying it, building a relationship with a technology or brand, and becoming practitioners.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer Relations is About Relationships, Not Sales
&lt;/h2&gt;

&lt;p&gt;DevRel operates on the front line of this Developer Marketing philosophy. DevRel demonstrates how a company's products help developers enjoy architecting something they can then be proud of. DevRel can elevate champions in the community and be the friendly, helpful, knowledgeable faces of an organization.&lt;/p&gt;

&lt;p&gt;DevRel is also &lt;strong&gt;uniquely positioned to be truly genuine with developers&lt;/strong&gt;. Is the product not the best suited for someone's situation? DevRel folks can outright say so! They can offer other solutions, and clarify when and how their company's products help — and when they don't. Unable to afford a commercial add-on from a company, but like to use their open source offerings? DevRel won't say "come back when you have the money." Instead, DevRel helps developers think through (or even build) an affordable alternative.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer Relations is Cross-Functional
&lt;/h2&gt;

&lt;p&gt;At the end of the day, no matter &lt;em&gt;what&lt;/em&gt; department DevRel lives in (or if DevRel is its &lt;em&gt;own&lt;/em&gt; department or reports to the Office of the CEO), DevRel is a heavily &lt;em&gt;cross-functional&lt;/em&gt; discipline.&lt;/p&gt;

&lt;p&gt;An effective DevRel team does not only build relationships with the community outside the company: it also builds relationships and collaborations &lt;em&gt;within&lt;/em&gt; the company and many — if not &lt;em&gt;most&lt;/em&gt; — of the other departments.&lt;/p&gt;

&lt;p&gt;For this reason, DevRel teams in Marketing have an advantage: Marketing departments have cohesive relationships with a lot of the rest of the organization already (Product, Customer Success, Support, Sales, Engineering, etc.). The teams &lt;em&gt;within&lt;/em&gt; Marketing are also key collaborators in DevRel's goals and mission (as discussed above), and working alongside them on a daily basis empowers DevRel to position itself optimally to have great reach and influence.&lt;/p&gt;

&lt;p&gt;So no matter what formal department your DevRel team lives in, Developer Relations as a discipline should follow the tenets that guide good Developer Marketing: be genuine, build trust, deliver value, and have fun bringing cool things to devs to make their lives better (and maybe even make money while doing it!).&lt;/p&gt;

</description>
      <category>devrel</category>
      <category>career</category>
      <category>tech</category>
    </item>
    <item>
      <title>Smarter &amp; Faster Angular Development with Nx</title>
      <dc:creator>Kim Maida</dc:creator>
      <pubDate>Wed, 28 Oct 2020 16:17:16 +0000</pubDate>
      <link>https://dev.to/nx/smarter-faster-angular-development-with-nx-26an</link>
      <guid>https://dev.to/nx/smarter-faster-angular-development-with-nx-26an</guid>
      <description>&lt;p&gt;&lt;a href="https://nrwl.io" rel="noopener noreferrer"&gt;Nrwl&lt;/a&gt; Architects &lt;a href="https://twitter.com/juristr" rel="noopener noreferrer"&gt;Juri Strumpflohner&lt;/a&gt; and &lt;a href="https://twitter.com/MannIsaac" rel="noopener noreferrer"&gt;Isaac Mann&lt;/a&gt; presented &lt;strong&gt;Smarter &amp;amp; Faster Angular Development with Nx&lt;/strong&gt;, a free, live &lt;a href="https://ng-conf.org" rel="noopener noreferrer"&gt;EnterpriseNG&lt;/a&gt; webinar for Angular developers in October, 2020. In case you missed the stream — or if you tuned in live but want to review the content again — the video and slides are available below.&lt;/p&gt;

&lt;h1&gt;
  
  
  What you will learn:
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Driving good architecture with &lt;a href="https://nx.dev" rel="noopener noreferrer"&gt;Nx&lt;/a&gt; using monorepo development: how Nx helps solve problems that developers face when structuring projects&lt;/li&gt;
&lt;li&gt;How Nx provides modern tools and improved developer experience (to learn more about &lt;a href="https://blog.nrwl.io/modern-angular-39b3f360f3d9" rel="noopener noreferrer"&gt;how Nx modernizes Angular, you can also check out this blog post&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Scalability and increased development and build speed with Nx&lt;/li&gt;
&lt;li&gt;Demos!&lt;/li&gt;
&lt;li&gt;Q&amp;amp;A&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can &lt;strong&gt;watch the full webinar&lt;/strong&gt; for free below 👇, or &lt;a href="https://docs.google.com/presentation/d/1vbRSFpV9jv_9rOo6naMDZn1Nhu1mnAudcRZkveQgoWs/edit" rel="noopener noreferrer"&gt;&lt;strong&gt;view the slides&lt;/strong&gt; by clicking here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/LEqJ1xKf_1w"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>angular</category>
      <category>nx</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Signing and Validating JSON Web Tokens (JWT) For Everyone</title>
      <dc:creator>Kim Maida</dc:creator>
      <pubDate>Sun, 27 Sep 2020 21:17:18 +0000</pubDate>
      <link>https://dev.to/kimmaida/signing-and-validating-json-web-tokens-jwt-for-everyone-25fb</link>
      <guid>https://dev.to/kimmaida/signing-and-validating-json-web-tokens-jwt-for-everyone-25fb</guid>
      <description>&lt;p&gt;When I started learning about &lt;a href="https://jwt.io/introduction/" rel="noopener noreferrer"&gt;JSON Web Tokens&lt;/a&gt;, there were some things that were straightforward to understand — &lt;em&gt;and&lt;/em&gt; some concepts that felt like &lt;em&gt;"hidden secrets"&lt;/em&gt; of JWT lore. 🧙‍♂️ &lt;/p&gt;

&lt;p&gt;This article aims to &lt;em&gt;demystify signing and validating JSON Web Tokens&lt;/em&gt;, with little need for security or cryptography knowledge.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; This article is a companion to my post on &lt;a href="https://dev.to/kimmaida/authorization-and-authentication-for-everyone-27j3"&gt;Authorization and Authentication for Everyone&lt;/a&gt;. I recommend that you read that post first.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  JSON Web Token (JWT) Recap
&lt;/h1&gt;

&lt;p&gt;JWTs are — in general terms — reasonably approachable. Information about them is readily available from many sources, chiefly covering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON Web Tokens (or JWT) are a &lt;strong&gt;compact, URL-safe way to transfer pieces of data between two parties&lt;/strong&gt; (such as an &lt;a href="https://dev.to/kimmaida/authorization-and-authentication-for-everyone-27j3#authorization-server"&gt;authorization server&lt;/a&gt; and an application).&lt;/li&gt;
&lt;li&gt;The JWT format is defined by &lt;a href="https://ietf.org/" rel="noopener noreferrer"&gt;IETF&lt;/a&gt; specification &lt;a href="https://tools.ietf.org/html/rfc7519" rel="noopener noreferrer"&gt;RFC 7519&lt;/a&gt; and is &lt;strong&gt;composed of three segments&lt;/strong&gt; (&lt;a href="https://dev.to/kimmaida/authorization-and-authentication-for-everyone-27j3#json-web-token-jwt"&gt;a &lt;em&gt;header&lt;/em&gt;, a &lt;em&gt;payload&lt;/em&gt;, and a &lt;em&gt;crypto&lt;/em&gt; segment&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;JWTs are &lt;strong&gt;&lt;em&gt;signed&lt;/em&gt; with a key&lt;/strong&gt; when they are generated and then &lt;strong&gt;&lt;em&gt;validated&lt;/em&gt; with a key&lt;/strong&gt; upon receipt so we can verify that they &lt;em&gt;haven't been modified in transit&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  The Challenge with Understanding JWT
&lt;/h1&gt;

&lt;p&gt;There's a meme about being introduced to a concept and then there are steps missing while you're expected to be able to get to the end result without knowing the steps in between. The meme demonstrates "How to draw an owl":&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy9q9pnwz72fwddhk09ls.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy9q9pnwz72fwddhk09ls.jpg" alt="1. " width="530" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To me, not being able to find approachable information about &lt;em&gt;signing and validating&lt;/em&gt; JWT felt like the missing steps to draw the owl.&lt;/p&gt;

&lt;p&gt;Most of the resources I dug up took me deep down the rabbit hole — until my head was swimming with mind-melting jargon, &lt;a href="https://en.wikipedia.org/wiki/Alice_and_Bob" rel="noopener noreferrer"&gt;Alices and Bobs&lt;/a&gt; (placeholder names used in cryptography examples), and complex maths. Instead of learning simpler, incremental steps to aid in my understanding, it felt like I was being given ten more complex, complete owl drawings.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why &lt;em&gt;Don't&lt;/em&gt; We Need to Know How Signing and Validation Work?
&lt;/h1&gt;

&lt;p&gt;Why is this? Why do most JWT resources simply say &lt;em&gt;"and then you sign and validate"&lt;/em&gt; and leave it at that?&lt;/p&gt;

&lt;p&gt;Think of it this way: for human beings to be effective or skilled with a tool, we don't need to know the intricacies of the tool's components.&lt;/p&gt;

&lt;p&gt;🚙 When you get into your car to drive to the grocery store, do you need to know how internal combustion works? You don't. &lt;/p&gt;

&lt;p&gt;🔋 When you charge your laptop, do you need to know what chemical reactions take place in a lithium ion battery to create the flow of electrons in a circuit to store and produce energy? Nope!&lt;/p&gt;

&lt;p&gt;We can still be good drivers or great computer programmers without intimate knowledge of these things. We trust that the manufacturers have used their expertise, specifications and standards, and due diligence to make useful tools for us to be more effective at the jobs we need those tools for.&lt;/p&gt;

&lt;p&gt;This is why &lt;strong&gt;&lt;em&gt;you don't need to know the exact process for signing and validating JWT in order to effectively use them&lt;/em&gt;&lt;/strong&gt; for authenticating and authorizing your applications and APIs.&lt;/p&gt;

&lt;p&gt;Okay, but you're reading this because you still want to know the missing steps to draw the owl. While you generally should not sign and validate tokens &lt;em&gt;yourself&lt;/em&gt; (seriously, &lt;em&gt;leave this to the experts&lt;/em&gt; — identity providers and &lt;a href="https://auth0.com" rel="noopener noreferrer"&gt;Identity-as-a-Service&lt;/a&gt; platforms!), knowing how it works can be helpful in making you feel more &lt;em&gt;comfortable&lt;/em&gt; with using JWTs. 😌&lt;/p&gt;

&lt;h1&gt;
  
  
  Anatomy of a JSON Web Token
&lt;/h1&gt;

&lt;p&gt;We covered the &lt;a href="https://dev.to/kimmaida/authorization-and-authentication-for-everyone-27j3#json-web-token-jwt"&gt;anatomy of JWT in depth in the previous blog article on authentication and authorization&lt;/a&gt;, but let's do a &lt;em&gt;very brief&lt;/em&gt; recap.&lt;/p&gt;

&lt;p&gt;JSON Web Tokens are composed of three URL-safe string segments concatenated with periods &lt;code&gt;.&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Header Segment
&lt;/h2&gt;

&lt;p&gt;The first segment is the &lt;strong&gt;header segment&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The header segment is a JSON object containing a signing algorithm and token type. It is &lt;a href="https://tools.ietf.org/html/rfc4648#section-5" rel="noopener noreferrer"&gt;&lt;code&gt;base64Url&lt;/code&gt; encoded&lt;/a&gt; (byte data represented as text that is URL and filename safe).&lt;/p&gt;

&lt;p&gt;Decoded, it looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"typ"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JWT"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Payload Segment
&lt;/h2&gt;

&lt;p&gt;The second segment is the &lt;strong&gt;payload segment&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is a JSON object containing &lt;em&gt;&lt;a href="https://dev.to/kimmaida/authorization-and-authentication-for-everyone-27j3#claims"&gt;data claims&lt;/a&gt;&lt;/em&gt;, which are statements about the user and the authentication event. This is the information that the JWT is conveying from one entity to another. Data claims might look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1234567890"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"admin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1516239022&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is also &lt;code&gt;base64Url&lt;/code&gt; encoded.&lt;/p&gt;

&lt;h2&gt;
  
  
  Crypto Segment
&lt;/h2&gt;

&lt;p&gt;The final segment is the &lt;strong&gt;crypto segment&lt;/strong&gt;, or &lt;strong&gt;signature&lt;/strong&gt;. JWTs are signed so they can't be modified in transit. When an &lt;a href="https://dev.to/kimmaida/authorization-and-authentication-for-everyone-27j3#authorization-server"&gt;authorization server issues a token&lt;/a&gt;, it signs it using a key.&lt;/p&gt;

&lt;p&gt;When the client receives the ID token, the client &lt;strong&gt;validates the signature&lt;/strong&gt; using a key as well. (If an asymmetric signing algorithm was used, different keys are used to sign and validate; if this is case, only the authorization server holds the ability to sign tokens.)&lt;/p&gt;

&lt;h1&gt;
  
  
  The Rest of the &lt;del&gt;Owl&lt;/del&gt; Signature
&lt;/h1&gt;

&lt;p&gt;This is where the missing steps of the &lt;del&gt;owl&lt;/del&gt; JWT signing / validation process are. Let's go through it step-by-step. &lt;/p&gt;

&lt;h2&gt;
  
  
  RS256 Signature
&lt;/h2&gt;

&lt;p&gt;For this article, I'm going to assume use of an RS256 signing algorithm. RS256 is an RSA &lt;a href="https://en.wikipedia.org/wiki/Digital_signature" rel="noopener noreferrer"&gt;Digital Signature&lt;/a&gt; Algorithm with &lt;a href="https://www.movable-type.co.uk/scripts/sha256.html" rel="noopener noreferrer"&gt;SHA-256&lt;/a&gt;. RSA256 is an Asymmetric Key Cryptography algorithm, which uses a pair of keys: a public key and a private key to encrypt and decrypt. In this case, the private key is used by the token issuer (authorization server), and the public key is used by the application receiving the token in order to validate it.&lt;/p&gt;

&lt;p&gt;If this feels jargon-laden and confusing right out of the gate, don't worry! Let's break it down into smaller, distinct steps.&lt;/p&gt;

&lt;h1&gt;
  
  
  The JWT Crypto Segment: Revisited
&lt;/h1&gt;

&lt;p&gt;Let's explore what the crypto segment &lt;em&gt;actually is&lt;/em&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Signing Input
&lt;/h2&gt;

&lt;p&gt;First we take the first two segments of the JWT (the header and the payload). In practice, that looks something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzpdq7s71y1in9s03n4wv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzpdq7s71y1in9s03n4wv.png" alt="header + payload segments" width="800" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In other words, this is the &lt;code&gt;base64Url&lt;/code&gt; encoded header and the &lt;code&gt;base64Url&lt;/code&gt; encoded payload, concatenated with a &lt;code&gt;.&lt;/code&gt; period:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8mhapuw3p0l8rlit2md7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8mhapuw3p0l8rlit2md7.png" alt="base64 URL encoded header + payload segments" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is what we call the &lt;strong&gt;signing input&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hashing
&lt;/h2&gt;

&lt;p&gt;We then &lt;strong&gt;hash the signing input&lt;/strong&gt; using the &lt;a href="https://www.movable-type.co.uk/scripts/sha256.html" rel="noopener noreferrer"&gt;SHA-256 hashing algorithm&lt;/a&gt;. Hashing converts one value into a different value. A &lt;em&gt;hash function&lt;/em&gt; uses a mathematical algorithm to generate a new value from an existing one.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hashing is irreversible. Once we have hashed an input, we &lt;em&gt;cannot&lt;/em&gt; get back to the original input again.&lt;/li&gt;
&lt;li&gt;Hashing will always produce the same output for the same input.&lt;/li&gt;
&lt;li&gt;No two different hashing inputs will produce the same output.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9vjn572h31htdlfixvqg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9vjn572h31htdlfixvqg.png" alt="SHA-256 hashed signing input" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point, we have a hash of the header and payload segments — which we could compare to other hashes, but &lt;em&gt;cannot&lt;/em&gt; reverse to return to the original signing input.&lt;/p&gt;

&lt;h2&gt;
  
  
  Encryption
&lt;/h2&gt;

&lt;p&gt;Next we &lt;strong&gt;encrypt&lt;/strong&gt; the hashed signing input. Unlike hashing, encryption &lt;em&gt;is reversible&lt;/em&gt;: we can &lt;em&gt;decrypt&lt;/em&gt; encrypted results (called ciphertext) to decipher the original input (plaintext).&lt;/p&gt;

&lt;p&gt;For this step, the &lt;em&gt;token issuer&lt;/em&gt; (authorization server) scrambles the hashed signing input using a &lt;strong&gt;private &lt;a href="https://medium.com/codeclan/what-are-encryption-keys-and-how-do-they-work-cc48c3053bd6" rel="noopener noreferrer"&gt;encryption key&lt;/a&gt;&lt;/strong&gt; to produce an output (ciphertext).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; I mentioned earlier that this example uses RSA, which is an asymmetric signing algorithm and uses one key to encrypt tokens, and another key to decrypt them. To learn more about this topic in an approachable, practical way, check out &lt;a href="https://www.youtube.com/watch?v=GSIDS_lvRv4" rel="noopener noreferrer"&gt;Public Key Cryptography by Computerphile on YouTube&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This final output (the hashed, encrypted, encoded header and payload) is the &lt;strong&gt;crypto segment&lt;/strong&gt; — or &lt;em&gt;signature&lt;/em&gt; — of the JWT.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F39wpzam9gk0c519q97hw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F39wpzam9gk0c519q97hw.png" alt="Encrypted, hashed signing input" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you'd like to dig much deeper into specifics of the RSA encryption algorithm itself, I recommend these great YouTube videos from &lt;a href="https://www.youtube.com/channel/UCq0EGvLTyy-LLT1oUSO_0FQ" rel="noopener noreferrer"&gt;Eddie Woo&lt;/a&gt;: &lt;a href="https://www.youtube.com/watch?v=4zahvcJ9glg" rel="noopener noreferrer"&gt;The RSA Encryption Algorithm&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There you have it. That's the signature of a JSON Web Token. 🎉&lt;/p&gt;

&lt;h1&gt;
  
  
  Validating the Signature
&lt;/h1&gt;

&lt;p&gt;Okay, we can start to understand how the token was signed — but that's only half of the story! The entire point of signing the token is so that whoever &lt;em&gt;receives&lt;/em&gt; the token can validate that this JWT contains data that hasn't been tampered with.&lt;/p&gt;

&lt;p&gt;How do applications validate JWTs?&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are We Working With?
&lt;/h2&gt;

&lt;p&gt;First, let's look at what information is available to the application that receives the token. We have access to the JWT itself: the &lt;em&gt;header&lt;/em&gt;, the &lt;em&gt;payload&lt;/em&gt;, and the &lt;em&gt;signature&lt;/em&gt; (aka, the crypto segment). We also have access to a &lt;em&gt;public key&lt;/em&gt;, which — as per its moniker — is freely available to the world.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; How are public keys made available? &lt;a href="https://tools.ietf.org/html/rfc7517" rel="noopener noreferrer"&gt;JSON Web Key (JWK) RFC 7517&lt;/a&gt; defines a specification for JSON representation of a cryptographic key. If you use an authorization server platform, the public key will be provided — and often helpfully encapsulated in an SDK or library that handles JWT validation for you. You can read more in this blog article: &lt;a href="https://auth0.com/blog/navigating-rs256-and-jwks/" rel="noopener noreferrer"&gt;Navigating RS256 and JWK&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Remember that the signature is the &lt;em&gt;encrypted, hashed header and payload&lt;/em&gt;. Hashing is irreversible, but encryption can be &lt;em&gt;decrypted&lt;/em&gt; (in this case, with the public key). Validation of the JWT is about getting to a point where we can effectively compare &lt;em&gt;what we received&lt;/em&gt; to &lt;em&gt;what we expect&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decode Claims
&lt;/h2&gt;

&lt;p&gt;The application can decode the header and payload to get some information. Recall that these two segments are &lt;code&gt;base64Url&lt;/code&gt; encoded to make them URL safe. There is nothing cryptographically magical or secure about decoding these segments; in fact, you can do so with a &lt;a href="https://www.base64decode.org/" rel="noopener noreferrer"&gt;simple online base64 decoding tool&lt;/a&gt;. Once they're decoded, we can easily read the information in them. For instance, we could decode the header segment to see what algorithm the JWT says it was signed with.&lt;/p&gt;

&lt;p&gt;On the other hand, the &lt;em&gt;signature&lt;/em&gt;'s purpose is to &lt;em&gt;validate&lt;/em&gt; that the information in the other segments is the same information that the authorization server sent — and that it hasn't been changed along the way.&lt;/p&gt;

&lt;p&gt;From the decoded header, we can see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"typ"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JWT"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our received token says that the algorithm is RS256. Our application should be configured to expect the algorithm that our authorization server (token issuer) uses. When we read the algorithm in the JWT's header, we should verify that it matches our &lt;em&gt;configured expectation&lt;/em&gt;. If it doesn't match, we should reject the token outright.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hashing (Again)
&lt;/h2&gt;

&lt;p&gt;If the algorithm in the token matches our expectation of RS256, we know we need to generate the SHA-256 hash of the header and payload segments. This will reproduce the signing input hash (again). Remember that hashing is irreversible, but the same input will always produce the same output. If we generate the hash from the header and payload we received, it &lt;em&gt;should&lt;/em&gt; match the header+payload hash that is encrypted in the signature.&lt;/p&gt;

&lt;p&gt;Therefore, we will hash the concatenated, &lt;code&gt;base64Url&lt;/code&gt; encoded header and payload. Now we have the signing input hash freshly calculated on the &lt;em&gt;application&lt;/em&gt; side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decryption
&lt;/h2&gt;

&lt;p&gt;The hashed signing input is also in the signature, but it's been encrypted by the authorization server (token issuer) with a private key. The application has the public key, so we can &lt;em&gt;decrypt&lt;/em&gt; the signature. Once this is done, we have access to the &lt;em&gt;original&lt;/em&gt; hash: the one generated by the authorization server when the token was first generated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compare Hashes
&lt;/h2&gt;

&lt;p&gt;Now we can &lt;strong&gt;compare the &lt;em&gt;decrypted&lt;/em&gt; hash to the &lt;em&gt;calculated&lt;/em&gt; hash&lt;/strong&gt;. If they are the same, then we've verified that the data in the JWT header and payload segments has not been modified between the time the authorization server created the token and the time our application received it. 🎊&lt;/p&gt;

&lt;h2&gt;
  
  
  + Verifying Token Claims
&lt;/h2&gt;

&lt;p&gt;Once we've validated the signature, there's &lt;a href="https://dev.to/kimmaida/authorization-and-authentication-for-everyone-27j3#authentication-with-id-tokens"&gt;more to verifying the JSON Web Token's data&lt;/a&gt;. Claims in the payload segment should &lt;em&gt;also&lt;/em&gt; be validated, because they contain information about the &lt;a href="https://dev.to/kimmaida/authorization-and-authentication-for-everyone-27j3#authentication-claims"&gt;token issuer, token expiration, intended audience for the token, information binding the token to the authorization request&lt;/a&gt;, and more.&lt;/p&gt;

&lt;p&gt;This data gives the receiving application vital details that the signature validation alone does not. For instance, examination of claims can reveal that a technically valid token was actually intended for a different application or user, has expired, came from an issuer that the application has no affiliation with, etc.&lt;/p&gt;

&lt;h1&gt;
  
  
  JWT Signing &amp;amp; Validation: Wrapping Up
&lt;/h1&gt;

&lt;p&gt;We've now covered signing JWT and validating JWT signatures.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwy7mbpd8ztvnnackbo87.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwy7mbpd8ztvnnackbo87.gif" alt="JWT crypto segment and validation" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My hope is that you feel confident your understanding of JWT signatures and validation has a few more steps filled in now:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1d70gc3c25ht8wutxtv8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1d70gc3c25ht8wutxtv8.png" alt="Owl with all steps" width="800" height="1071"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's still important to reiterate that, as a developer, &lt;strong&gt;you most likely will never need to &lt;em&gt;implement&lt;/em&gt; these processes yourself&lt;/strong&gt;. And in fact, unless your engineering focus is security and identity, you probably &lt;em&gt;shouldn't&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Identity platforms like &lt;a href="https://auth0.com" rel="noopener noreferrer"&gt;Auth0&lt;/a&gt;, &lt;a href="https://okta.com" rel="noopener noreferrer"&gt;Okta&lt;/a&gt;, &lt;a href="https://pingidentity.com" rel="noopener noreferrer"&gt;Ping Identity&lt;/a&gt;, and more &lt;em&gt;do all of this for you&lt;/em&gt;: issuing and signing tokens on the authorization server side, and providing SDKs and libraries for validation and token management on the application or API side.&lt;/p&gt;




&lt;h1&gt;
  
  
  Resources and What's Next?
&lt;/h1&gt;

&lt;p&gt;As I mentioned at the beginning, this article is a companion and supplement to &lt;a href="https://dev.to/kimmaida/authorization-and-authentication-for-everyone-27j3"&gt;Authorization and Authentication for Everyone&lt;/a&gt;, which is a much more comprehensive resource on the history of OAuth, OpenID Connect, authorization servers, JSON Web Tokens, API authorization, delegation with scopes, and more. Please check it out if you'd like to go further into identity topics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn More
&lt;/h2&gt;

&lt;p&gt;In an effort to create a digestible introduction to signing and validating JWTs that is widely approachable (and is the introduction I wished &lt;em&gt;I'd&lt;/em&gt; had), I have simplified topics that are incredibly rich and complex.&lt;/p&gt;

&lt;p&gt;🧠 To learn much more, try starting with some of the following resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=GSIDS_lvRv4" rel="noopener noreferrer"&gt;Public Key Cryptography&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/codeclan/what-are-encryption-keys-and-how-do-they-work-cc48c3053bd6" rel="noopener noreferrer"&gt;What Are Encryption Keys and How Do They Work?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=4zahvcJ9glg" rel="noopener noreferrer"&gt;The RSA Encryption Algorithm - Part 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/oOcTVTpUsPQ" rel="noopener noreferrer"&gt;The RSA Encryption Algorithm - Part 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://auth0.com/docs/videos/learn-identity" rel="noopener noreferrer"&gt;Learn Identity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jwt.io" rel="noopener noreferrer"&gt;JWT.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Thank You!
&lt;/h2&gt;

&lt;p&gt;If you'd like to chat, I'm available on Twitter at &lt;a href="https://twitter.com/KimMaida" rel="noopener noreferrer"&gt;@KimMaida&lt;/a&gt;, and I also speak at &lt;a href="https://github.com/kmaida#-events" rel="noopener noreferrer"&gt;conferences and events&lt;/a&gt; — at least, I did before COVID-19. I hope to see you sometime, and &lt;strong&gt;thank you so much for reading&lt;/strong&gt;!&lt;/p&gt;

</description>
      <category>jwt</category>
      <category>identity</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Authorization and Authentication for Everyone</title>
      <dc:creator>Kim Maida</dc:creator>
      <pubDate>Mon, 20 Jul 2020 16:16:49 +0000</pubDate>
      <link>https://dev.to/auth0ambassadors/authorization-and-authentication-for-everyone-4ol8</link>
      <guid>https://dev.to/auth0ambassadors/authorization-and-authentication-for-everyone-4ol8</guid>
      <description>&lt;p&gt;Authentication and authorization are necessary for many of the applications we build. Maybe you've developed apps and implemented authentication and authorization in them — possibly by importing a third party auth library or by using an identity platform.&lt;/p&gt;

&lt;p&gt;Maybe you got the job done, but you really weren't clear on &lt;em&gt;what&lt;/em&gt; was happening behind the scenes, or &lt;em&gt;why&lt;/em&gt; things were being done a certain way. If you'd like to build a foundational understanding of what goes on behind the scenes when using OAuth 2.0 and OpenID Connect standards, read on!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;Authentication is hard.&lt;/em&gt;&lt;/strong&gt; Why is this? Auth standards are well defined — but challenging to get right. And that's okay! We're going to go through it in an approachable way. We'll address the &lt;strong&gt;concepts of identity step by step, building on our knowledge as we go along.&lt;/strong&gt; By the time we're done, you should have a foundation and know where you might want to dig deeper.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This post is meant to be read from beginning to end. We'll build on top of each concept to layer knowledge when it makes sense to introduce new topics. Please keep that in mind if you're jumping around in the content.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;OAuth 2.0&lt;/li&gt;
&lt;li&gt;The Login Problem&lt;/li&gt;
&lt;li&gt;OpenID Connect&lt;/li&gt;
&lt;li&gt;Authentication with ID Tokens&lt;/li&gt;
&lt;li&gt;Accessing APIs with Access Tokens&lt;/li&gt;
&lt;li&gt;Delegation with Scopes&lt;/li&gt;
&lt;li&gt;Resources and What's Next?&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;When I told family or friends that I "work in identity," they often assumed that meant I was employed by the government issuing driver's licenses, or that I helped people resolve credit card fraud.&lt;/p&gt;

&lt;p&gt;However, neither were true. I &lt;a href="https://auth0.com" rel="noopener noreferrer"&gt;formerly worked for Auth0&lt;/a&gt;, a company that manages &lt;em&gt;digital identity&lt;/em&gt;. (I'm now a member of the &lt;a href="https://auth0.com/ambassador-program" rel="noopener noreferrer"&gt;Auth0 Ambassadors program&lt;/a&gt;, and a &lt;a href="https://developers.google.com/" rel="noopener noreferrer"&gt;Google Developer Expert&lt;/a&gt; in SPPI: Security, Privacy, Payments, and Identity.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Digital Identity
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Digital identity&lt;/strong&gt; refers to a set of attributes that define an individual user in the context of a function delivered by a particular application.&lt;/p&gt;

&lt;p&gt;What does that mean?&lt;/p&gt;

&lt;p&gt;Say you run an online shoe retail company. The &lt;em&gt;digital identity&lt;/em&gt; of your app's users might be their credit card number, shipping address, and purchase history. Their digital identity is contextual to &lt;em&gt;your&lt;/em&gt; app.&lt;/p&gt;

&lt;p&gt;This leads us to...&lt;/p&gt;

&lt;h3&gt;
  
  
  Authentication
&lt;/h3&gt;

&lt;p&gt;In a broad sense, &lt;strong&gt;authentication&lt;/strong&gt; refers to the process of verifying that a user is who they say they are. &lt;/p&gt;

&lt;p&gt;Once a system has been able to establish this, we come to...&lt;/p&gt;

&lt;h3&gt;
  
  
  Authorization
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Authorization&lt;/strong&gt; deals with granting or denying rights to access resources. &lt;/p&gt;

&lt;h3&gt;
  
  
  Standards
&lt;/h3&gt;

&lt;p&gt;You may recall that I mentioned that auth is guided by clearly-defined standards. But where do these standards come from in the first place?&lt;/p&gt;

&lt;p&gt;There are many different standards and organizations that govern how things work on the internet. Two bodies that are of &lt;em&gt;particular interest to us in the context of authentication and authorization&lt;/em&gt; are the Internet Engineering Task Force (IETF) and the OpenID Foundation (OIDF).&lt;/p&gt;

&lt;h4&gt;
  
  
  IETF (Internet Engineering Task Force)
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://ietf.org" rel="noopener noreferrer"&gt;IETF&lt;/a&gt; is a large, open, international community of network designers, operators, vendors, and researchers who are concerned with the evolution of internet architecture and the smooth operation of the internet.&lt;/p&gt;

&lt;p&gt;Really, that's a fancy way to say that &lt;strong&gt;dedicated professionals cooperate to write technical documents that guide us in how things should be done on the internet.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  OIDF (OpenID Foundation)
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://openid.net/foundation/" rel="noopener noreferrer"&gt;OIDF&lt;/a&gt; is a non-profit, international  organization of people and companies who are committed to enabling, promoting, and protecting OpenID technologies.&lt;/p&gt;

&lt;p&gt;Now that we are aware of the specs and who writes them, let's circle back around to &lt;em&gt;authorization&lt;/em&gt; and talk about:&lt;/p&gt;

&lt;h1&gt;
  
  
  OAuth 2.0
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://tools.ietf.org/html/rfc6749" rel="noopener noreferrer"&gt;OAuth 2.0&lt;/a&gt; is one of the most frequently mentioned specs when it comes to the web — and also one that is &lt;em&gt;often mis-represented or misunderstood&lt;/em&gt;. How so?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;OAuth is not an authentication spec.&lt;/em&gt; OAuth deals with &lt;em&gt;delegated authorization&lt;/em&gt;. Remember that authentication is about verifying the identity of a user. Authorization deals with granting or denying access to resources. OAuth 2.0 grants access to applications on the behalf of users. (Don't worry, we'll get to the authentication part in a little bit!)&lt;/p&gt;

&lt;h2&gt;
  
  
  Before OAuth
&lt;/h2&gt;

&lt;p&gt;To understand the purpose of OAuth, we need to do go back in time. OAuth 1.0 was established in December 2007. Before then, if we needed to &lt;strong&gt;access third party resources&lt;/strong&gt;, it looked like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcc4mwm3l6ix0h4hzc71.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcc4mwm3l6ix0h4hzc71.gif" alt="Before OAuth" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's say you used an app called HireMe123. HireMe123 wants to set up a calendar event (such as an interview appointment) on your (the user's) behalf. HireMe123 doesn't have its own calendar; it wants to use another service called MyCalApp to add events.&lt;/p&gt;

&lt;p&gt;Once you were logged into HireMe123, HireMe123 would &lt;em&gt;ask you for your MyCalApp login credentials&lt;/em&gt;. You would enter your MyCalApp username and password into HireMe123's site.&lt;/p&gt;

&lt;p&gt;HireMe123 then used your MyCalApp login to gain access to MyCalApp's API, and could then create calendar events using &lt;em&gt;your&lt;/em&gt; MyCalApp credentials.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sharing Credentials is Bad!
&lt;/h3&gt;

&lt;p&gt;This approach relied on sharing a user's personal credentials from one app with a completely different app, and this is &lt;strong&gt;not good&lt;/strong&gt;. How so?&lt;/p&gt;

&lt;p&gt;For one thing, HireMe123 had &lt;em&gt;much less at stake&lt;/em&gt; in the protection of your MyCalApp login information. If HireMe123 didn't protect your MyCalApp credentials appropriately and they ended up stolen or breached, someone might write some nasty blog articles, but &lt;em&gt;HireMe123&lt;/em&gt; wouldn't face a catastrophe the way MyCalApp would.&lt;/p&gt;

&lt;p&gt;HireMe123 also had &lt;em&gt;way too much access&lt;/em&gt; to MyCalApp. HireMe123 had the same amount of access that you did, because they used your credentials to gain that access. That meant that HireMe123 could read all your calendar events, delete events, modify your calendar settings, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter OAuth
&lt;/h2&gt;

&lt;p&gt;This leads us to OAuth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OAuth 2.0&lt;/strong&gt; is an open standard for performing delegated authorization. It's a specification that tells us how to grant third party access to APIs without exposing credentials. &lt;/p&gt;

&lt;p&gt;Using OAuth, the user can now &lt;em&gt;delegate&lt;/em&gt; HireMe123 to call MyCalApp on the user's behalf. MyCalApp can limit access to its API when called by third party clients without the risks of sharing login information or providing &lt;em&gt;too much&lt;/em&gt; access. It does this using an:&lt;/p&gt;

&lt;h2&gt;
  
  
  Authorization Server
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;authorization server&lt;/strong&gt; is a set of endpoints to interact with the user and issue tokens. How does this help?&lt;/p&gt;

&lt;p&gt;Let's revisit the situation with HireMe123 and MyCalApp, only now we have OAuth 2.0:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uoywh86pn5lta9dk30h.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uoywh86pn5lta9dk30h.gif" alt="Authorization with OAuth 2.0" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MyCalApp now has an authorization server. Let's assume that HireMe123 has already registered as a known client with MyCalApp, which means that MyCalApp's authorization server recognizes HireMe123 as an entity that may ask for access to its API.&lt;/p&gt;

&lt;p&gt;Let's also assume you're already logged in with HireMe123 through whatever authentication HireMe123 has set up for itself. HireMe123 now wants to create events on your behalf.&lt;/p&gt;

&lt;p&gt;HireMe123 sends an &lt;em&gt;authorization request&lt;/em&gt; to MyCalApp's authorization server. In response, MyCalApp's authorization server prompts you — the user — to log in with MyCalApp (if you're not already logged in). You authenticate with MyCalApp.&lt;/p&gt;

&lt;p&gt;The MyCalApp authorization server then &lt;em&gt;prompts you for your consent&lt;/em&gt; to allow HireMe123 to access MyCalApp's APIs on your behalf. A prompt opens in the browser and specifically asks for your consent to let HireMe123 &lt;em&gt;add calendar events&lt;/em&gt; (but no more than that).&lt;/p&gt;

&lt;p&gt;If you say yes and grant your consent, then the MyCalApp authorization server will send an &lt;em&gt;authorization code&lt;/em&gt; to HireMe123. This lets HireMe123 know that the MyCalApp user (you) did indeed agree to allow HireMe123 to add events using the user's (your) MyCalApp.&lt;/p&gt;

&lt;p&gt;MyCalApp will then issue an &lt;em&gt;access token&lt;/em&gt; to HireMe123. HireMe123 can use that access token to call the MyCalApp API within the scope of permissions that were accepted by you and create events for you using the MyCalApp API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nothing insidious is happening now!&lt;/strong&gt; &lt;em&gt;MyCalApp is asking the user to log in with MyCalApp&lt;/em&gt;. HireMe123 is &lt;em&gt;not&lt;/em&gt; asking for the user's MyCalApp credentials. The issues with sharing credentials and too much access are no longer a problem.&lt;/p&gt;

&lt;h4&gt;
  
  
  What About Authentication?
&lt;/h4&gt;

&lt;p&gt;At this point, I hope it's been made clear that &lt;em&gt;OAuth is for delegated access&lt;/em&gt;. It doesn't cover &lt;em&gt;authentication&lt;/em&gt;. At any point where authentication was involved in the processes we covered above, login was managed by whatever login process HireMe123 or MyCalApp had implemented at their own discretion. OAuth 2.0 &lt;em&gt;didn't prescribe how&lt;/em&gt; this should be done: it only covered authorizing third party API access.&lt;/p&gt;

&lt;p&gt;So why are authentication and OAuth so often mentioned in the same breath?&lt;/p&gt;

&lt;h1&gt;
  
  
  The Login Problem
&lt;/h1&gt;

&lt;p&gt;The thing that happened after OAuth 2.0 established a way to access third party APIs was that &lt;em&gt;apps also wanted to log users in with other accounts&lt;/em&gt;. Using our example: let's say HireMe123 wanted a MyCalApp user to be able to &lt;em&gt;log into HireMe123 using their MyCalApp account&lt;/em&gt;, despite not having signed up for a HireMe123 account.&lt;/p&gt;

&lt;p&gt;But as we mentioned above, &lt;strong&gt;OAuth 2.0 is for delegated access&lt;/strong&gt;. It is &lt;em&gt;not&lt;/em&gt; an authentication protocol. That didn't stop people from trying to use it like one though, and this presented problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems with Using Access Tokens for Authentication
&lt;/h2&gt;

&lt;p&gt;If HireMe123 assumes successfully calling MyCalApp's API with an access token means the &lt;em&gt;user&lt;/em&gt; can be considered authenticated with HireMe123, we run into problems because we have no way to verify the access token was issued to a particular individual.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Someone could have stolen the access token from a different user&lt;/li&gt;
&lt;li&gt;The access token could have been obtained from another client (not HireMe123) and injected into HireMe123&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is called the &lt;strong&gt;confused deputy problem&lt;/strong&gt;. HireMe123 doesn't know &lt;em&gt;where&lt;/em&gt; this token came from or &lt;em&gt;who&lt;/em&gt; it was issued for. If we recall: &lt;strong&gt;authentication is about verifying the user is who they say they are&lt;/strong&gt;. HireMe123 can't know this from the fact that it can use this access token to access an API.&lt;/p&gt;

&lt;p&gt;As mentioned, this didn't stop people from misusing access tokens and OAuth 2.0 for authentication anyway. It quickly became evident that formalization of authentication &lt;em&gt;on top of OAuth 2.0&lt;/em&gt; was necessary to allow logins with third party applications while keeping apps and their users safe.&lt;/p&gt;

&lt;h1&gt;
  
  
  OpenID Connect
&lt;/h1&gt;

&lt;p&gt;This brings us to the specification called &lt;a href="https://openid.net/specs" rel="noopener noreferrer"&gt;OpenID Connect&lt;/a&gt;, or OIDC. OIDC is a spec &lt;em&gt;on top of OAuth 2.0&lt;/em&gt; that says how to authenticate users. The &lt;a href="https://openid.net/foundation/" rel="noopener noreferrer"&gt;OpenID Foundation (OIDF)&lt;/a&gt; is the steward of the OIDC standards.&lt;/p&gt;

&lt;p&gt;OIDC is an identity layer for authenticating users with an authorization server. Remember that an authorization server &lt;em&gt;issues tokens&lt;/em&gt;. &lt;strong&gt;Tokens&lt;/strong&gt; are encoded pieces of data for transmitting information between parties (such as an authorization server, application, or resource API). In the case of OIDC and authentication, the authorization server issues &lt;em&gt;ID tokens&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ID Tokens
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ID tokens&lt;/strong&gt; provide information about the authentication event and they identify the user. ID tokens are &lt;em&gt;intended for the client&lt;/em&gt;. They're a fixed format that the client can parse and validate to extract identity information from the token and thereby authenticate the user.&lt;/p&gt;

&lt;p&gt;OIDC declares a &lt;em&gt;fixed format&lt;/em&gt; for ID tokens, which is:&lt;/p&gt;

&lt;h3&gt;
  
  
  JSON Web Token (JWT)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://tools.ietf.org/html/rfc7519" rel="noopener noreferrer"&gt;JSON Web Tokens&lt;/a&gt;, or &lt;a href="https://jwt.io" rel="noopener noreferrer"&gt;JWT&lt;/a&gt; (sometimes pronounced "jot"), are composed of three URL-safe string segments concatenated with periods &lt;code&gt;.&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Header Segment
&lt;/h4&gt;

&lt;p&gt;The first segment is the &lt;strong&gt;header segment&lt;/strong&gt;. It might look something like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The header segment is a JSON object containing a signing algorithm and token type. It is &lt;a href="https://tools.ietf.org/html/rfc4648#section-5" rel="noopener noreferrer"&gt;&lt;code&gt;base64Url&lt;/code&gt; encoded&lt;/a&gt; (byte data represented as text that is URL and filename safe).&lt;/p&gt;

&lt;p&gt;Decoded, it looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"typ"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JWT"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Payload Segment
&lt;/h4&gt;

&lt;p&gt;The second segment is the &lt;strong&gt;payload segment&lt;/strong&gt;. It might look like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is a JSON object containing data &lt;em&gt;claims&lt;/em&gt;, which are statements about the user and the authentication event. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1234567890"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"admin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1516239022&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is also &lt;code&gt;base64Url&lt;/code&gt; encoded.&lt;/p&gt;

&lt;h4&gt;
  
  
  Crypto Segment
&lt;/h4&gt;

&lt;p&gt;The final segment is the &lt;strong&gt;crypto segment&lt;/strong&gt;, or &lt;strong&gt;signature&lt;/strong&gt;. JWTs are signed so they can't be modified in transit. When an authorization server issues a token, it signs it using a key.&lt;/p&gt;

&lt;p&gt;When the client receives the ID token, the client &lt;strong&gt;validates the signature&lt;/strong&gt; using a key as well. (If an asymmetric signing algorithm was used, different keys are used to sign and validate; if this is case, only the authorization server holds the ability to sign tokens.)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Don't worry if this seems confusing. The details of how this works shouldn't trouble you or keep you from effectively using an authorization server with token-based authentication. If you're interested in demystifying the terms, jargon, and details behind JWT signing, check out my article on &lt;a href="https://dev.to/kimmaida/signing-and-validating-json-web-tokens-jwt-for-everyone-25fb"&gt;Signing and Validating JSON Web Tokens (JWT) for Everyone&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Claims
&lt;/h3&gt;

&lt;p&gt;Now that we know about the &lt;em&gt;anatomy&lt;/em&gt; of a JWT, let's talk more about the &lt;strong&gt;claims&lt;/strong&gt;, those statements from the Payload Segment. As per their moniker, ID tokens provide &lt;em&gt;identity&lt;/em&gt; information, which is present in the claims.&lt;/p&gt;

&lt;h4&gt;
  
  
  Authentication Claims
&lt;/h4&gt;

&lt;p&gt;We'll start with &lt;em&gt;&lt;a href="https://openid.net/specs/openid-connect-core-1_0.html#IDToken" rel="noopener noreferrer"&gt;statements about the authentication event&lt;/a&gt;&lt;/em&gt;. Here are a few examples of these claims:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iss"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://{you}.authz-server.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"aud"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RxHBtq2HL6biPljKRLNByqehlKhN1nCx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1570019636365&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"iat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1570016110289&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"nonce"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3yAjXLPq8EPP0S"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some of the required authentication claims in an ID token include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;iss&lt;/code&gt; &lt;em&gt;(issuer)&lt;/em&gt;: the issuer of the JWT, e.g., the authorization server&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aud&lt;/code&gt; &lt;em&gt;(audience)&lt;/em&gt;: the intended recipient of the JWT; for ID tokens, this must be the client ID of the application receiving the token&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;exp&lt;/code&gt; &lt;em&gt;(expiration time)&lt;/em&gt;: expiration time; the ID token must not be accepted after this time&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;iat&lt;/code&gt; &lt;em&gt;(issued at time)&lt;/em&gt;: time at which the ID token was issued&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;code&gt;nonce&lt;/code&gt; &lt;em&gt;binds the client's authorization request to the token it receives&lt;/em&gt;. The nonce is a &lt;a href="https://auth0.com/docs/api-auth/tutorials/nonce" rel="noopener noreferrer"&gt;cryptographically random string&lt;/a&gt; that the client creates and sends with an authorization request. The authorization server then places the nonce in the token that is sent back to the app. The app verifies that the nonce in the token matches the one sent with the authorization request. This way, the app can verify that the token came from the place it requested the token from in the first place.&lt;/p&gt;

&lt;h4&gt;
  
  
  Identity Claims
&lt;/h4&gt;

&lt;p&gt;Claims also include &lt;em&gt;&lt;a href="https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims" rel="noopener noreferrer"&gt;statements about the end user&lt;/a&gt;&lt;/em&gt;.  Here are a few examples of these claims:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"google-oauth2|102582972157289381734"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Kim Maida"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"picture"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://gravatar[...]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"twitter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://twitter.com/KimMaida"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"kim@gatsbyjs.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some of the standard profile claims in an ID token include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sub&lt;/code&gt; &lt;em&gt;(subject)&lt;/em&gt;: unique identifier for the user; required&lt;/li&gt;
&lt;li&gt;&lt;code&gt;email&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;email_verified&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;birthdate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;etc.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We've now been through a crash-course on the important specifications (OAuth 2.0 and OpenID Connect) and it's time to see how to &lt;strong&gt;put our identity knowledge to work&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Authentication with ID Tokens
&lt;/h1&gt;

&lt;p&gt;Let's see OIDC authentication in practice.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note that this is a simplified diagram. There are a few different flows depending on your application architecture.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftqure8mdp07rl8jr93ck.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftqure8mdp07rl8jr93ck.gif" alt="authentication with ID tokens in the browser" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our entities here are: the &lt;em&gt;browser&lt;/em&gt;, an &lt;em&gt;application&lt;/em&gt; running in the browser, and the &lt;em&gt;authorization server&lt;/em&gt;. When a user wants to log in, the app sends an authorization request to the authorization server. The user's credentials are verified by the authorization server, and if everything checks out, the authorization server issues an ID token to the application.&lt;/p&gt;

&lt;p&gt;The client application then decodes the ID token (which is a JWT) and verifies it. This includes validating the signature, and we must also verify the claims. Some examples of claim verification include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;issuer (&lt;code&gt;iss&lt;/code&gt;): was this token issued by the expected authorization server?&lt;/li&gt;
&lt;li&gt;audience (&lt;code&gt;aud&lt;/code&gt;): is our app the target recipient of this token?&lt;/li&gt;
&lt;li&gt;expiration (&lt;code&gt;exp&lt;/code&gt;): is this token within a valid timeframe for use?&lt;/li&gt;
&lt;li&gt;nonce (&lt;code&gt;nonce&lt;/code&gt;): can we tie this token back to the authorization request our app made?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once we've established the authenticity of the ID token, the user is &lt;em&gt;authenticated&lt;/em&gt;. We also now have access to the identity claims and know &lt;em&gt;who&lt;/em&gt; this user is.&lt;/p&gt;

&lt;p&gt;Now the user is &lt;em&gt;authenticated&lt;/em&gt;. It's time to interact with an API.&lt;/p&gt;

&lt;h1&gt;
  
  
  Accessing APIs with Access Tokens
&lt;/h1&gt;

&lt;p&gt;We talked a bit about access tokens earlier, back when we were looking at how delegated access works with OAuth 2.0 and authorization servers. Let's look at some of the &lt;em&gt;details&lt;/em&gt; of how that works, going back to our scenario with HireMe123 and MyCalApp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Access Tokens
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Access tokens&lt;/strong&gt; are used for &lt;em&gt;granting access to resources&lt;/em&gt;. With an access token issued by MyCalApp's authorization server, HireMe123 can access MyCalApp's API.&lt;/p&gt;

&lt;p&gt;Unlike ID tokens, which OIDC declares as JSON Web Tokens, &lt;strong&gt;access tokens have no specific, defined format&lt;/strong&gt;. They do not have to be (and aren't necessarily) JWT. However, many identity solutions use JWTs for access tokens because the format enables validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Access Tokens are Opaque to the Client
&lt;/h3&gt;

&lt;p&gt;Access tokens are for the &lt;em&gt;resource API&lt;/em&gt; and it is important that they are &lt;strong&gt;opaque to the client.&lt;/strong&gt; Why? &lt;/p&gt;

&lt;p&gt;Access tokens can change at any time. They should have short expiration times, so a user may frequently get new ones. They can also be re-issued to access different APIs or exercise different permissions. The &lt;em&gt;client&lt;/em&gt; application should never contain code that relies on the contents of the access token. Code that does so would be brittle, and is almost guaranteed to break.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessing Resource APIs
&lt;/h2&gt;

&lt;p&gt;Let's say we want to use an access token to call an API from a Single Page Application. What does this look like?&lt;/p&gt;

&lt;p&gt;We've covered authentication above, so let's assume the user is logged into our JS app in the browser. The app sends an authorization request to the authorization server, requesting an access token to call an API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0nbp89ovuqa14ikg4gt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0nbp89ovuqa14ikg4gt.gif" alt="Accessing an API with an access token" width="537" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then when our app wants to interact with the API, we attach the access token to the request header, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# HTTP request headers&lt;/span&gt;
Authorization: &lt;span class="s1"&gt;'Bearer eyj[...]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The authorized request is then sent to the API, which verifies the token using middleware. If everything checks out, then the API returns data (e.g., JSON) to the application running in the browser.&lt;/p&gt;

&lt;p&gt;This is great, but there's something that may be occurring to you right about now. Earlier, we stated that OAuth solves problems with too much access. So how is that being addressed here?&lt;/p&gt;

&lt;h2&gt;
  
  
  Delegation with Scopes
&lt;/h2&gt;

&lt;p&gt;How does the API know what level of access it should give to the application that's requesting use of its API? We do this with &lt;strong&gt;scopes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Scopes "&lt;a href="https://auth0.com/blog/on-the-nature-of-oauth2-scopes" rel="noopener noreferrer"&gt;limit what an application can do on the behalf of a user&lt;/a&gt;." They &lt;strong&gt;cannot grant privileges the user doesn't already have&lt;/strong&gt;. For example, if the MyCalApp user doesn't have permission to set up new MyCalApp enterprise accounts, scopes granted to &lt;em&gt;HireMe123&lt;/em&gt; won't ever allow the user to set up new enterprise accounts either.&lt;/p&gt;

&lt;p&gt;Scopes &lt;strong&gt;delegate access control&lt;/strong&gt; to the API or resource. The API is then responsible for &lt;em&gt;combining incoming scopes with actual user privileges&lt;/em&gt; to make the appropriate access control decisions.&lt;/p&gt;

&lt;p&gt;Let's walk through this with an example. &lt;/p&gt;

&lt;p&gt;I'm using the HireMe123 app and HireMe123 wants to access the third party MyCalApp API to create events on my behalf. HireMe123 has already requested an access token for MyCalApp from MyCalApp's authorization server. This token has some important information in it, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sub&lt;/code&gt;: (my MyCalApp user ID)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aud&lt;/code&gt;: &lt;code&gt;MyCalAppAPI&lt;/code&gt; (audience stating this token is intended for the MyCalApp API)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;scope&lt;/code&gt;: &lt;code&gt;write:events&lt;/code&gt; (scope saying HireMe123 has permission to use the API to write events to my calendar)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HireMe123 sends a request to the MyCalApp API with the access token in its authorization header. When the MyCalApp API receives this request, it can see that the token contains a &lt;code&gt;write:events&lt;/code&gt; scope.&lt;/p&gt;

&lt;p&gt;But MyCalApp hosts calendar accounts for &lt;em&gt;hundreds of thousands of users&lt;/em&gt;. In addition to looking at the &lt;code&gt;scope&lt;/code&gt; in the token, MyCalApp's API middleware needs to check the &lt;code&gt;sub&lt;/code&gt; subject identifier to make sure this request from HireMe123 is only able to exercise &lt;em&gt;my&lt;/em&gt; privileges to create events with &lt;em&gt;my&lt;/em&gt; MyCalApp account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4i76ltyqgq3rfukmrn0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4i76ltyqgq3rfukmrn0.gif" alt="delegated authorization with scopes and API access control" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the context of delegated authorization, scopes express what an application can do on the user's behalf. They're a subset of the user's total capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Granting Consent
&lt;/h3&gt;

&lt;p&gt;Remember when the authorization server asked the HireMe123 user for their consent to allow HireMe123 to use the user's privileges to access MyCalApp?&lt;/p&gt;

&lt;p&gt;That consent dialog might look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22vtspdyqbyruyyxr0it.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22vtspdyqbyruyyxr0it.gif" alt="consent dialog flow: HireMe123 is requesting access to your MyCalApp account to write:calendars" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HireMe123 could ask for a variety of different scopes, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;write:events&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;read:events&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;read:settings&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;write:settings&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;...etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In general, we should avoid overloading scopes with user-specific privileges. Scopes are for delegated permissions for an application. However, it &lt;em&gt;is&lt;/em&gt; possible to add different scopes to individual users if your authorization server provides &lt;a href="https://auth0.com/docs/authorization/concepts/rbac" rel="noopener noreferrer"&gt;Role-Based Access Control (RBAC)&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;With &lt;strong&gt;RBAC&lt;/strong&gt;, you can set up user roles with specific permissions in your authorization server. Then when the authorization server issues access tokens, it can include a specific user's roles in their scopes.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Resources and What's Next?
&lt;/h1&gt;

&lt;p&gt;We covered a &lt;em&gt;lot&lt;/em&gt; of material, and it still wasn't anywhere close to everything. I do hope this was a helpful crash course in identity, authorization, and authentication. &lt;/p&gt;

&lt;p&gt;I'm currently working on a few additional blog posts that go into further depth on JSON Web Tokens and authentication and authorization for JavaScript applications.&lt;/p&gt;

&lt;p&gt;If you'd like to learn much, much more on these topics, here are some great resources for you to further your knowledge:&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn More
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://auth0.com/docs/videos/learn-identity" rel="noopener noreferrer"&gt;Learn Identity&lt;/a&gt; video series&lt;/strong&gt; in the &lt;a href="https://auth0.com/docs" rel="noopener noreferrer"&gt;Auth0 docs&lt;/a&gt; is the lecture portion of the new hire identity training for engineers at &lt;a href="https://auth0.com" rel="noopener noreferrer"&gt;Auth0&lt;/a&gt;, presented by Principal Architect &lt;a href="https://auth0.com/blog/auth0-welcomes-vittorio-bertocci/" rel="noopener noreferrer"&gt;Vittorio Bertocci&lt;/a&gt;. If you'd like to learn identity the way it’s done at Auth0, it's completely free and available to everyone (you don't even have to pay with a tweet or email!).&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;OAuth 2.0 and OpenID Connect specifications&lt;/strong&gt; are dense, but once you're familiar with the terminology and have foundational identity knowledge, they're helpful, informative, and become much more digestible. Check them out here: &lt;a href="https://tools.ietf.org/html/rfc6749" rel="noopener noreferrer"&gt;The OAuth 2.0 Authorization Framework&lt;/a&gt; and &lt;a href="https://openid.net/developers/specs/" rel="noopener noreferrer"&gt;OpenID Connect Specifications&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://jwt.io" rel="noopener noreferrer"&gt;JWT.io&lt;/a&gt;&lt;/strong&gt; is a JSON Web Token resource that provides a debugger tool and directory of JWT signing/verification libraries for various technologies.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://openidconnect.net/" rel="noopener noreferrer"&gt;OpenID Connect Playground&lt;/a&gt;&lt;/strong&gt; is a debugger that lets developers explore and test OIDC calls and responses step-by-step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank You!
&lt;/h2&gt;

&lt;p&gt;If you'd like to chat, I'm available on Twitter at &lt;a href="https://twitter.com/KimMaida" rel="noopener noreferrer"&gt;@KimMaida&lt;/a&gt;, and I also speak at &lt;a href="https://github.com/kmaida/about#events" rel="noopener noreferrer"&gt;conferences and events&lt;/a&gt;. I hope to see you sometime, and &lt;strong&gt;thank you so much for reading&lt;/strong&gt;!&lt;/p&gt;

</description>
      <category>authentication</category>
      <category>authorization</category>
      <category>oidc</category>
      <category>oauth2</category>
    </item>
    <item>
      <title>Authorization and Authentication For Everyone</title>
      <dc:creator>Kim Maida</dc:creator>
      <pubDate>Sun, 19 Jul 2020 17:45:09 +0000</pubDate>
      <link>https://dev.to/kimmaida/authorization-and-authentication-for-everyone-27j3</link>
      <guid>https://dev.to/kimmaida/authorization-and-authentication-for-everyone-27j3</guid>
      <description>&lt;p&gt;Authentication and authorization are necessary for many of the applications we build. Maybe you've developed apps and implemented authentication and authorization in them — possibly by importing a third party auth library or by using an identity platform.&lt;/p&gt;

&lt;p&gt;Maybe you got the job done, but you really weren't clear on &lt;em&gt;what&lt;/em&gt; was happening behind the scenes, or &lt;em&gt;why&lt;/em&gt; things were being done a certain way. If you'd like to build a foundational understanding of what goes on behind the scenes when using OAuth 2.0 and OpenID Connect standards, read on!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;Authentication is hard.&lt;/em&gt;&lt;/strong&gt; Why is this? Auth standards are well defined — but challenging to get right. And that's okay! We're going to go through it in an approachable way. We'll address the &lt;strong&gt;concepts of identity step by step, building on our knowledge as we go along.&lt;/strong&gt; By the time we're done, you should have a foundation and know where you might want to dig deeper.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This post is meant to be read from beginning to end. We'll build on top of each concept to layer knowledge when it makes sense to introduce new topics. Please keep that in mind if you're jumping around in the content.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;OAuth 2.0&lt;/li&gt;
&lt;li&gt;The Login Problem&lt;/li&gt;
&lt;li&gt;OpenID Connect&lt;/li&gt;
&lt;li&gt;Authentication with ID Tokens&lt;/li&gt;
&lt;li&gt;Accessing APIs with Access Tokens&lt;/li&gt;
&lt;li&gt;Delegation with Scopes&lt;/li&gt;
&lt;li&gt;Resources and What's Next?&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;When I told family or friends that I "work in identity," they often assumed that meant I was employed by the government issuing driver's licenses, or that I helped people resolve credit card fraud.&lt;/p&gt;

&lt;p&gt;However, neither were true. I &lt;a href="https://auth0.com" rel="noopener noreferrer"&gt;formerly worked for Auth0&lt;/a&gt;, a company that manages &lt;em&gt;digital identity&lt;/em&gt;. (I'm now a member of the &lt;a href="https://auth0.com/ambassador-program" rel="noopener noreferrer"&gt;Auth0 Ambassadors program&lt;/a&gt;, and a &lt;a href="https://developers.google.com/" rel="noopener noreferrer"&gt;Google Developer Expert&lt;/a&gt; in SPPI: Security, Privacy, Payments, and Identity.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Digital Identity
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Digital identity&lt;/strong&gt; refers to a set of attributes that define an individual user in the context of a function delivered by a particular application.&lt;/p&gt;

&lt;p&gt;What does that mean?&lt;/p&gt;

&lt;p&gt;Say you run an online shoe retail company. The &lt;em&gt;digital identity&lt;/em&gt; of your app's users might be their credit card number, shipping address, and purchase history. Their digital identity is contextual to &lt;em&gt;your&lt;/em&gt; app.&lt;/p&gt;

&lt;p&gt;This leads us to...&lt;/p&gt;

&lt;h3&gt;
  
  
  Authentication
&lt;/h3&gt;

&lt;p&gt;In a broad sense, &lt;strong&gt;authentication&lt;/strong&gt; refers to the process of verifying that a user is who they say they are. &lt;/p&gt;

&lt;p&gt;Once a system has been able to establish this, we come to...&lt;/p&gt;

&lt;h3&gt;
  
  
  Authorization
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Authorization&lt;/strong&gt; deals with granting or denying rights to access resources. &lt;/p&gt;

&lt;h3&gt;
  
  
  Standards
&lt;/h3&gt;

&lt;p&gt;You may recall that I mentioned that auth is guided by clearly-defined standards. But where do these standards come from in the first place?&lt;/p&gt;

&lt;p&gt;There are many different standards and organizations that govern how things work on the internet. Two bodies that are of &lt;em&gt;particular interest to us in the context of authentication and authorization&lt;/em&gt; are the Internet Engineering Task Force (IETF) and the OpenID Foundation (OIDF).&lt;/p&gt;

&lt;h4&gt;
  
  
  IETF (Internet Engineering Task Force)
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://ietf.org" rel="noopener noreferrer"&gt;IETF&lt;/a&gt; is a large, open, international community of network designers, operators, vendors, and researchers who are concerned with the evolution of internet architecture and the smooth operation of the internet.&lt;/p&gt;

&lt;p&gt;Really, that's a fancy way to say that &lt;strong&gt;dedicated professionals cooperate to write technical documents that guide us in how things should be done on the internet.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  OIDF (OpenID Foundation)
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://openid.net/foundation/" rel="noopener noreferrer"&gt;OIDF&lt;/a&gt; is a non-profit, international  organization of people and companies who are committed to enabling, promoting, and protecting OpenID technologies.&lt;/p&gt;

&lt;p&gt;Now that we are aware of the specs and who writes them, let's circle back around to &lt;em&gt;authorization&lt;/em&gt; and talk about:&lt;/p&gt;

&lt;h1&gt;
  
  
  OAuth 2.0
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://tools.ietf.org/html/rfc6749" rel="noopener noreferrer"&gt;OAuth 2.0&lt;/a&gt; is one of the most frequently mentioned specs when it comes to the web — and also one that is &lt;em&gt;often mis-represented or misunderstood&lt;/em&gt;. How so?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;OAuth is not an authentication spec.&lt;/em&gt; OAuth deals with &lt;em&gt;delegated authorization&lt;/em&gt;. Remember that authentication is about verifying the identity of a user. Authorization deals with granting or denying access to resources. OAuth 2.0 grants access to applications on the behalf of users. (Don't worry, we'll get to the authentication part in a little bit!)&lt;/p&gt;

&lt;h2&gt;
  
  
  Before OAuth
&lt;/h2&gt;

&lt;p&gt;To understand the purpose of OAuth, we need to do go back in time. OAuth 1.0 was established in December 2007. Before then, if we needed to &lt;strong&gt;access third party resources&lt;/strong&gt;, it looked like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcc4mwm3l6ix0h4hzc71.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcc4mwm3l6ix0h4hzc71.gif" alt="Before OAuth" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's say you used an app called HireMe123. HireMe123 wants to set up a calendar event (such as an interview appointment) on your (the user's) behalf. HireMe123 doesn't have its own calendar; it wants to use another service called MyCalApp to add events.&lt;/p&gt;

&lt;p&gt;Once you were logged into HireMe123, HireMe123 would &lt;em&gt;ask you for your MyCalApp login credentials&lt;/em&gt;. You would enter your MyCalApp username and password into HireMe123's site.&lt;/p&gt;

&lt;p&gt;HireMe123 then used your MyCalApp login to gain access to MyCalApp's API, and could then create calendar events using &lt;em&gt;your&lt;/em&gt; MyCalApp credentials.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sharing Credentials is Bad!
&lt;/h3&gt;

&lt;p&gt;This approach relied on sharing a user's personal credentials from one app with a completely different app, and this is &lt;strong&gt;not good&lt;/strong&gt;. How so?&lt;/p&gt;

&lt;p&gt;For one thing, HireMe123 had &lt;em&gt;much less at stake&lt;/em&gt; in the protection of your MyCalApp login information. If HireMe123 didn't protect your MyCalApp credentials appropriately and they ended up stolen or breached, someone might write some nasty blog articles, but &lt;em&gt;HireMe123&lt;/em&gt; wouldn't face a catastrophe the way MyCalApp would.&lt;/p&gt;

&lt;p&gt;HireMe123 also had &lt;em&gt;way too much access&lt;/em&gt; to MyCalApp. HireMe123 had the same amount of access that you did, because they used your credentials to gain that access. That meant that HireMe123 could read all your calendar events, delete events, modify your calendar settings, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter OAuth
&lt;/h2&gt;

&lt;p&gt;This leads us to OAuth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OAuth 2.0&lt;/strong&gt; is an open standard for performing delegated authorization. It's a specification that tells us how to grant third party access to APIs without exposing credentials. &lt;/p&gt;

&lt;p&gt;Using OAuth, the user can now &lt;em&gt;delegate&lt;/em&gt; HireMe123 to call MyCalApp on the user's behalf. MyCalApp can limit access to its API when called by third party clients without the risks of sharing login information or providing &lt;em&gt;too much&lt;/em&gt; access. It does this using an:&lt;/p&gt;

&lt;h2&gt;
  
  
  Authorization Server
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;authorization server&lt;/strong&gt; is a set of endpoints to interact with the user and issue tokens. How does this help?&lt;/p&gt;

&lt;p&gt;Let's revisit the situation with HireMe123 and MyCalApp, only now we have OAuth 2.0:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uoywh86pn5lta9dk30h.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uoywh86pn5lta9dk30h.gif" alt="Authorization with OAuth 2.0" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MyCalApp now has an authorization server. Let's assume that HireMe123 has already registered as a known client with MyCalApp, which means that MyCalApp's authorization server recognizes HireMe123 as an entity that may ask for access to its API.&lt;/p&gt;

&lt;p&gt;Let's also assume you're already logged in with HireMe123 through whatever authentication HireMe123 has set up for itself. HireMe123 now wants to create events on your behalf.&lt;/p&gt;

&lt;p&gt;HireMe123 sends an &lt;em&gt;authorization request&lt;/em&gt; to MyCalApp's authorization server. In response, MyCalApp's authorization server prompts you — the user — to log in with MyCalApp (if you're not already logged in). You authenticate with MyCalApp.&lt;/p&gt;

&lt;p&gt;The MyCalApp authorization server then &lt;em&gt;prompts you for your consent&lt;/em&gt; to allow HireMe123 to access MyCalApp's APIs on your behalf. A prompt opens in the browser and specifically asks for your consent to let HireMe123 &lt;em&gt;add calendar events&lt;/em&gt; (but no more than that).&lt;/p&gt;

&lt;p&gt;If you say yes and grant your consent, then the MyCalApp authorization server will send an &lt;em&gt;authorization code&lt;/em&gt; to HireMe123. This lets HireMe123 know that the MyCalApp user (you) did indeed agree to allow HireMe123 to add events using the user's (your) MyCalApp.&lt;/p&gt;

&lt;p&gt;MyCalApp will then issue an &lt;em&gt;access token&lt;/em&gt; to HireMe123. HireMe123 can use that access token to call the MyCalApp API within the scope of permissions that were accepted by you and create events for you using the MyCalApp API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nothing insidious is happening now!&lt;/strong&gt; &lt;em&gt;MyCalApp is asking the user to log in with MyCalApp&lt;/em&gt;. HireMe123 is &lt;em&gt;not&lt;/em&gt; asking for the user's MyCalApp credentials. The issues with sharing credentials and too much access are no longer a problem.&lt;/p&gt;

&lt;h4&gt;
  
  
  What About Authentication?
&lt;/h4&gt;

&lt;p&gt;At this point, I hope it's been made clear that &lt;em&gt;OAuth is for delegated access&lt;/em&gt;. It doesn't cover &lt;em&gt;authentication&lt;/em&gt;. At any point where authentication was involved in the processes we covered above, login was managed by whatever login process HireMe123 or MyCalApp had implemented at their own discretion. OAuth 2.0 &lt;em&gt;didn't prescribe how&lt;/em&gt; this should be done: it only covered authorizing third party API access.&lt;/p&gt;

&lt;p&gt;So why are authentication and OAuth so often mentioned in the same breath?&lt;/p&gt;

&lt;h1&gt;
  
  
  The Login Problem
&lt;/h1&gt;

&lt;p&gt;The thing that happened after OAuth 2.0 established a way to access third party APIs was that &lt;em&gt;apps also wanted to log users in with other accounts&lt;/em&gt;. Using our example: let's say HireMe123 wanted a MyCalApp user to be able to &lt;em&gt;log into HireMe123 using their MyCalApp account&lt;/em&gt;, despite not having signed up for a HireMe123 account.&lt;/p&gt;

&lt;p&gt;But as we mentioned above, &lt;strong&gt;OAuth 2.0 is for delegated access&lt;/strong&gt;. It is &lt;em&gt;not&lt;/em&gt; an authentication protocol. That didn't stop people from trying to use it like one though, and this presented problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems with Using Access Tokens for Authentication
&lt;/h2&gt;

&lt;p&gt;If HireMe123 assumes successfully calling MyCalApp's API with an access token means the &lt;em&gt;user&lt;/em&gt; can be considered authenticated with HireMe123, we run into problems because we have no way to verify the access token was issued to a particular individual.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Someone could have stolen the access token from a different user&lt;/li&gt;
&lt;li&gt;The access token could have been obtained from another client (not HireMe123) and injected into HireMe123&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is called the &lt;strong&gt;confused deputy problem&lt;/strong&gt;. HireMe123 doesn't know &lt;em&gt;where&lt;/em&gt; this token came from or &lt;em&gt;who&lt;/em&gt; it was issued for. If we recall: &lt;strong&gt;authentication is about verifying the user is who they say they are&lt;/strong&gt;. HireMe123 can't know this from the fact that it can use this access token to access an API.&lt;/p&gt;

&lt;p&gt;As mentioned, this didn't stop people from misusing access tokens and OAuth 2.0 for authentication anyway. It quickly became evident that formalization of authentication &lt;em&gt;on top of OAuth 2.0&lt;/em&gt; was necessary to allow logins with third party applications while keeping apps and their users safe.&lt;/p&gt;

&lt;h1&gt;
  
  
  OpenID Connect
&lt;/h1&gt;

&lt;p&gt;This brings us to the specification called &lt;a href="https://openid.net/specs" rel="noopener noreferrer"&gt;OpenID Connect&lt;/a&gt;, or OIDC. OIDC is a spec &lt;em&gt;on top of OAuth 2.0&lt;/em&gt; that says how to authenticate users. The &lt;a href="https://openid.net/foundation/" rel="noopener noreferrer"&gt;OpenID Foundation (OIDF)&lt;/a&gt; is the steward of the OIDC standards.&lt;/p&gt;

&lt;p&gt;OIDC is an identity layer for authenticating users with an authorization server. Remember that an authorization server &lt;em&gt;issues tokens&lt;/em&gt;. &lt;strong&gt;Tokens&lt;/strong&gt; are encoded pieces of data for transmitting information between parties (such as an authorization server, application, or resource API). In the case of OIDC and authentication, the authorization server issues &lt;em&gt;ID tokens&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ID Tokens
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ID tokens&lt;/strong&gt; provide information about the authentication event and they identify the user. ID tokens are &lt;em&gt;intended for the client&lt;/em&gt;. They're a fixed format that the client can parse and validate to extract identity information from the token and thereby authenticate the user.&lt;/p&gt;

&lt;p&gt;OIDC declares a &lt;em&gt;fixed format&lt;/em&gt; for ID tokens, which is:&lt;/p&gt;

&lt;h3&gt;
  
  
  JSON Web Token (JWT)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://tools.ietf.org/html/rfc7519" rel="noopener noreferrer"&gt;JSON Web Tokens&lt;/a&gt;, or &lt;a href="https://jwt.io" rel="noopener noreferrer"&gt;JWT&lt;/a&gt; (sometimes pronounced "jot"), are composed of three URL-safe string segments concatenated with periods &lt;code&gt;.&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Header Segment
&lt;/h4&gt;

&lt;p&gt;The first segment is the &lt;strong&gt;header segment&lt;/strong&gt;. It might look something like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The header segment is a JSON object containing a signing algorithm and token type. It is &lt;a href="https://tools.ietf.org/html/rfc4648#section-5" rel="noopener noreferrer"&gt;&lt;code&gt;base64Url&lt;/code&gt; encoded&lt;/a&gt; (byte data represented as text that is URL and filename safe).&lt;/p&gt;

&lt;p&gt;Decoded, it looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"typ"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JWT"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Payload Segment
&lt;/h4&gt;

&lt;p&gt;The second segment is the &lt;strong&gt;payload segment&lt;/strong&gt;. It might look like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is a JSON object containing data &lt;em&gt;claims&lt;/em&gt;, which are statements about the user and the authentication event. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1234567890"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"admin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1516239022&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is also &lt;code&gt;base64Url&lt;/code&gt; encoded.&lt;/p&gt;

&lt;h4&gt;
  
  
  Crypto Segment
&lt;/h4&gt;

&lt;p&gt;The final segment is the &lt;strong&gt;crypto segment&lt;/strong&gt;, or &lt;strong&gt;signature&lt;/strong&gt;. JWTs are signed so they can't be modified in transit. When an authorization server issues a token, it signs it using a key.&lt;/p&gt;

&lt;p&gt;When the client receives the ID token, the client &lt;strong&gt;validates the signature&lt;/strong&gt; using a key as well. (If an asymmetric signing algorithm was used, different keys are used to sign and validate; if this is case, only the authorization server holds the ability to sign tokens.)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Don't worry if this seems confusing. The details of how this works shouldn't trouble you or keep you from effectively using an authorization server with token-based authentication. If you're interested in demystifying the terms, jargon, and details behind JWT signing, check out my article on &lt;a href="https://dev.to/kimmaida/signing-and-validating-json-web-tokens-jwt-for-everyone-25fb"&gt;Signing and Validating JSON Web Tokens (JWT) for Everyone&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Claims
&lt;/h3&gt;

&lt;p&gt;Now that we know about the &lt;em&gt;anatomy&lt;/em&gt; of a JWT, let's talk more about the &lt;strong&gt;claims&lt;/strong&gt;, those statements from the Payload Segment. As per their moniker, ID tokens provide &lt;em&gt;identity&lt;/em&gt; information, which is present in the claims.&lt;/p&gt;

&lt;h4&gt;
  
  
  Authentication Claims
&lt;/h4&gt;

&lt;p&gt;We'll start with &lt;em&gt;&lt;a href="https://openid.net/specs/openid-connect-core-1_0.html#IDToken" rel="noopener noreferrer"&gt;statements about the authentication event&lt;/a&gt;&lt;/em&gt;. Here are a few examples of these claims:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iss"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://{you}.authz-server.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"aud"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RxHBtq2HL6biPljKRLNByqehlKhN1nCx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1570019636365&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"iat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1570016110289&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"nonce"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3yAjXLPq8EPP0S"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some of the required authentication claims in an ID token include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;iss&lt;/code&gt; &lt;em&gt;(issuer)&lt;/em&gt;: the issuer of the JWT, e.g., the authorization server&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aud&lt;/code&gt; &lt;em&gt;(audience)&lt;/em&gt;: the intended recipient of the JWT; for ID tokens, this must be the client ID of the application receiving the token&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;exp&lt;/code&gt; &lt;em&gt;(expiration time)&lt;/em&gt;: expiration time; the ID token must not be accepted after this time&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;iat&lt;/code&gt; &lt;em&gt;(issued at time)&lt;/em&gt;: time at which the ID token was issued&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;code&gt;nonce&lt;/code&gt; &lt;em&gt;binds the client's authorization request to the token it receives&lt;/em&gt;. The nonce is a &lt;a href="https://auth0.com/docs/api-auth/tutorials/nonce" rel="noopener noreferrer"&gt;cryptographically random string&lt;/a&gt; that the client creates and sends with an authorization request. The authorization server then places the nonce in the token that is sent back to the app. The app verifies that the nonce in the token matches the one sent with the authorization request. This way, the app can verify that the token came from the place it requested the token from in the first place.&lt;/p&gt;

&lt;h4&gt;
  
  
  Identity Claims
&lt;/h4&gt;

&lt;p&gt;Claims also include &lt;em&gt;&lt;a href="https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims" rel="noopener noreferrer"&gt;statements about the end user&lt;/a&gt;&lt;/em&gt;.  Here are a few examples of these claims:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"google-oauth2|102582972157289381734"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Kim Maida"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"picture"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://gravatar[...]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"twitter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://twitter.com/KimMaida"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"kim@gatsbyjs.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some of the standard profile claims in an ID token include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sub&lt;/code&gt; &lt;em&gt;(subject)&lt;/em&gt;: unique identifier for the user; required&lt;/li&gt;
&lt;li&gt;&lt;code&gt;email&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;email_verified&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;birthdate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;etc.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We've now been through a crash-course on the important specifications (OAuth 2.0 and OpenID Connect) and it's time to see how to &lt;strong&gt;put our identity knowledge to work&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Authentication with ID Tokens
&lt;/h1&gt;

&lt;p&gt;Let's see OIDC authentication in practice.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note that this is a simplified diagram. There are a few different flows depending on your application architecture.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftqure8mdp07rl8jr93ck.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftqure8mdp07rl8jr93ck.gif" alt="authentication with ID tokens in the browser" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our entities here are: the &lt;em&gt;browser&lt;/em&gt;, an &lt;em&gt;application&lt;/em&gt; running in the browser, and the &lt;em&gt;authorization server&lt;/em&gt;. When a user wants to log in, the app sends an authorization request to the authorization server. The user's credentials are verified by the authorization server, and if everything checks out, the authorization server issues an ID token to the application.&lt;/p&gt;

&lt;p&gt;The client application then decodes the ID token (which is a JWT) and verifies it. This includes validating the signature, and we must also verify the claims. Some examples of claim verification include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;issuer (&lt;code&gt;iss&lt;/code&gt;): was this token issued by the expected authorization server?&lt;/li&gt;
&lt;li&gt;audience (&lt;code&gt;aud&lt;/code&gt;): is our app the target recipient of this token?&lt;/li&gt;
&lt;li&gt;expiration (&lt;code&gt;exp&lt;/code&gt;): is this token within a valid timeframe for use?&lt;/li&gt;
&lt;li&gt;nonce (&lt;code&gt;nonce&lt;/code&gt;): can we tie this token back to the authorization request our app made?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once we've established the authenticity of the ID token, the user is &lt;em&gt;authenticated&lt;/em&gt;. We also now have access to the identity claims and know &lt;em&gt;who&lt;/em&gt; this user is.&lt;/p&gt;

&lt;p&gt;Now the user is &lt;em&gt;authenticated&lt;/em&gt;. It's time to interact with an API.&lt;/p&gt;

&lt;h1&gt;
  
  
  Accessing APIs with Access Tokens
&lt;/h1&gt;

&lt;p&gt;We talked a bit about access tokens earlier, back when we were looking at how delegated access works with OAuth 2.0 and authorization servers. Let's look at some of the &lt;em&gt;details&lt;/em&gt; of how that works, going back to our scenario with HireMe123 and MyCalApp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Access Tokens
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Access tokens&lt;/strong&gt; are used for &lt;em&gt;granting access to resources&lt;/em&gt;. With an access token issued by MyCalApp's authorization server, HireMe123 can access MyCalApp's API.&lt;/p&gt;

&lt;p&gt;Unlike ID tokens, which OIDC declares as JSON Web Tokens, &lt;strong&gt;access tokens have no specific, defined format&lt;/strong&gt;. They do not have to be (and aren't necessarily) JWT. However, many identity solutions use JWTs for access tokens because the format enables validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Access Tokens are Opaque to the Client
&lt;/h3&gt;

&lt;p&gt;Access tokens are for the &lt;em&gt;resource API&lt;/em&gt; and it is important that they are &lt;strong&gt;opaque to the client.&lt;/strong&gt; Why? &lt;/p&gt;

&lt;p&gt;Access tokens can change at any time. They should have short expiration times, so a user may frequently get new ones. They can also be re-issued to access different APIs or exercise different permissions. The &lt;em&gt;client&lt;/em&gt; application should never contain code that relies on the contents of the access token. Code that does so would be brittle, and is almost guaranteed to break.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessing Resource APIs
&lt;/h2&gt;

&lt;p&gt;Let's say we want to use an access token to call an API from a Single Page Application. What does this look like?&lt;/p&gt;

&lt;p&gt;We've covered authentication above, so let's assume the user is logged into our JS app in the browser. The app sends an authorization request to the authorization server, requesting an access token to call an API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0nbp89ovuqa14ikg4gt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0nbp89ovuqa14ikg4gt.gif" alt="Accessing an API with an access token" width="537" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then when our app wants to interact with the API, we attach the access token to the request header, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# HTTP request headers&lt;/span&gt;
Authorization: &lt;span class="s1"&gt;'Bearer eyj[...]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The authorized request is then sent to the API, which verifies the token using middleware. If everything checks out, then the API returns data (e.g., JSON) to the application running in the browser.&lt;/p&gt;

&lt;p&gt;This is great, but there's something that may be occurring to you right about now. Earlier, we stated that OAuth solves problems with too much access. So how is that being addressed here?&lt;/p&gt;

&lt;h2&gt;
  
  
  Delegation with Scopes
&lt;/h2&gt;

&lt;p&gt;How does the API know what level of access it should give to the application that's requesting use of its API? We do this with &lt;strong&gt;scopes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Scopes "&lt;a href="https://auth0.com/blog/on-the-nature-of-oauth2-scopes" rel="noopener noreferrer"&gt;limit what an application can do on the behalf of a user&lt;/a&gt;." They &lt;strong&gt;cannot grant privileges the user doesn't already have&lt;/strong&gt;. For example, if the MyCalApp user doesn't have permission to set up new MyCalApp enterprise accounts, scopes granted to &lt;em&gt;HireMe123&lt;/em&gt; won't ever allow the user to set up new enterprise accounts either.&lt;/p&gt;

&lt;p&gt;Scopes &lt;strong&gt;delegate access control&lt;/strong&gt; to the API or resource. The API is then responsible for &lt;em&gt;combining incoming scopes with actual user privileges&lt;/em&gt; to make the appropriate access control decisions.&lt;/p&gt;

&lt;p&gt;Let's walk through this with an example. &lt;/p&gt;

&lt;p&gt;I'm using the HireMe123 app and HireMe123 wants to access the third party MyCalApp API to create events on my behalf. HireMe123 has already requested an access token for MyCalApp from MyCalApp's authorization server. This token has some important information in it, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sub&lt;/code&gt;: (my MyCalApp user ID)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aud&lt;/code&gt;: &lt;code&gt;MyCalAppAPI&lt;/code&gt; (audience stating this token is intended for the MyCalApp API)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;scope&lt;/code&gt;: &lt;code&gt;write:events&lt;/code&gt; (scope saying HireMe123 has permission to use the API to write events to my calendar)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HireMe123 sends a request to the MyCalApp API with the access token in its authorization header. When the MyCalApp API receives this request, it can see that the token contains a &lt;code&gt;write:events&lt;/code&gt; scope.&lt;/p&gt;

&lt;p&gt;But MyCalApp hosts calendar accounts for &lt;em&gt;hundreds of thousands of users&lt;/em&gt;. In addition to looking at the &lt;code&gt;scope&lt;/code&gt; in the token, MyCalApp's API middleware needs to check the &lt;code&gt;sub&lt;/code&gt; subject identifier to make sure this request from HireMe123 is only able to exercise &lt;em&gt;my&lt;/em&gt; privileges to create events with &lt;em&gt;my&lt;/em&gt; MyCalApp account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4i76ltyqgq3rfukmrn0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4i76ltyqgq3rfukmrn0.gif" alt="delegated authorization with scopes and API access control" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the context of delegated authorization, scopes express what an application can do on the user's behalf. They're a subset of the user's total capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Granting Consent
&lt;/h3&gt;

&lt;p&gt;Remember when the authorization server asked the HireMe123 user for their consent to allow HireMe123 to use the user's privileges to access MyCalApp?&lt;/p&gt;

&lt;p&gt;That consent dialog might look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22vtspdyqbyruyyxr0it.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22vtspdyqbyruyyxr0it.gif" alt="consent dialog flow: HireMe123 is requesting access to your MyCalApp account to write:calendars" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HireMe123 could ask for a variety of different scopes, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;write:events&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;read:events&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;read:settings&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;write:settings&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;...etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In general, we should avoid overloading scopes with user-specific privileges. Scopes are for delegated permissions for an application. However, it &lt;em&gt;is&lt;/em&gt; possible to add different scopes to individual users if your authorization server provides &lt;a href="https://auth0.com/docs/authorization/concepts/rbac" rel="noopener noreferrer"&gt;Role-Based Access Control (RBAC)&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;With &lt;strong&gt;RBAC&lt;/strong&gt;, you can set up user roles with specific permissions in your authorization server. Then when the authorization server issues access tokens, it can include a specific user's roles in their scopes.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Resources and What's Next?
&lt;/h1&gt;

&lt;p&gt;We covered a &lt;em&gt;lot&lt;/em&gt; of material, and it still wasn't anywhere close to everything. I do hope this was a helpful crash course in identity, authorization, and authentication. &lt;/p&gt;

&lt;p&gt;To further demystify JWT, read my article &lt;a href="https://dev.to/kimmaida/signing-and-validating-json-web-tokens-jwt-for-everyone-25fb"&gt;Signing and Validating JSON Web Tokens for Everyone&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you'd like to learn much, much more on these topics, here are some great resources for you to further your knowledge:&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn More
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://auth0.com/docs/videos/learn-identity" rel="noopener noreferrer"&gt;Learn Identity&lt;/a&gt; video series&lt;/strong&gt; in the &lt;a href="https://auth0.com/docs" rel="noopener noreferrer"&gt;Auth0 docs&lt;/a&gt; is the lecture portion of the new hire identity training for engineers at &lt;a href="https://auth0.com" rel="noopener noreferrer"&gt;Auth0&lt;/a&gt;, presented by Principal Architect &lt;a href="https://auth0.com/blog/auth0-welcomes-vittorio-bertocci/" rel="noopener noreferrer"&gt;Vittorio Bertocci&lt;/a&gt;. If you'd like to learn identity the way it’s done at Auth0, it's completely free and available to everyone (you don't even have to pay with a tweet or email!).&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;OAuth 2.0 and OpenID Connect specifications&lt;/strong&gt; are dense, but once you're familiar with the terminology and have foundational identity knowledge, they're helpful, informative, and become much more digestible. Check them out here: &lt;a href="https://tools.ietf.org/html/rfc6749" rel="noopener noreferrer"&gt;The OAuth 2.0 Authorization Framework&lt;/a&gt; and &lt;a href="https://openid.net/developers/specs/" rel="noopener noreferrer"&gt;OpenID Connect Specifications&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://jwt.io" rel="noopener noreferrer"&gt;JWT.io&lt;/a&gt;&lt;/strong&gt; is a JSON Web Token resource that provides a debugger tool and directory of JWT signing/verification libraries for various technologies.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://openidconnect.net/" rel="noopener noreferrer"&gt;OpenID Connect Playground&lt;/a&gt;&lt;/strong&gt; is a debugger that lets developers explore and test OIDC calls and responses step-by-step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank You!
&lt;/h2&gt;

&lt;p&gt;If you'd like to chat, I'm available on Twitter at &lt;a href="https://twitter.com/KimMaida" rel="noopener noreferrer"&gt;@KimMaida&lt;/a&gt;, and I also speak at &lt;a href="https://github.com/kmaida#-events" rel="noopener noreferrer"&gt;conferences and events&lt;/a&gt; — at least, I did before COVID-19. I have delivered this content in presentation format, and hope to do so again once travel and in-person events resume. I hope to see you sometime, and &lt;strong&gt;thank you so much for reading&lt;/strong&gt;!&lt;/p&gt;

</description>
      <category>authorization</category>
      <category>security</category>
      <category>authentication</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Hello, Rota! A Slackbot for Rotation Management</title>
      <dc:creator>Kim Maida</dc:creator>
      <pubDate>Sun, 10 May 2020 17:57:17 +0000</pubDate>
      <link>https://dev.to/kimmaida/hello-rota-a-slackbot-for-rotation-management-216c</link>
      <guid>https://dev.to/kimmaida/hello-rota-a-slackbot-for-rotation-management-216c</guid>
      <description>&lt;h1&gt;
  
  
  Improving Remote Work Through Internal Tooling
&lt;/h1&gt;

&lt;p&gt;Ever since I started working &lt;em&gt;fully remote&lt;/em&gt; 4-ish years ago, I've been interested in the tools and automation that makes peoples' lives easier in tech remote work culture.&lt;/p&gt;

&lt;p&gt;I'd like to give a shout-out to my former employer here: &lt;a href="https://auth0.com" rel="noopener noreferrer"&gt;Auth0&lt;/a&gt; pioneered my appreciation for automation tools in Slack and their customizability, flexibility, and power for making remote communication and workflows appear to &lt;em&gt;just work&lt;/em&gt;, automagically.&lt;/p&gt;

&lt;p&gt;In fact, prior to my arrival at the company, Auth0 had built a &lt;code&gt;@concierge&lt;/code&gt; Slackbot that was so integrated into the company culture that I thought it was a &lt;em&gt;core feature of Slack itself&lt;/em&gt;. It wasn't until I'd moved onto my next role that I realized &lt;code&gt;@concierge&lt;/code&gt; had been built custom &lt;em&gt;for&lt;/em&gt; Auth0 &lt;em&gt;by&lt;/em&gt; Auth0 dev tools engineers. The &lt;a href="https://auth0.com/blog/auth0-internal-dev-tools-unleashing-engineering-potential/" rel="noopener noreferrer"&gt;Developer Tools team at Auth0 builds solutions and toolchains for the company&lt;/a&gt;, internally, to vastly improve productivity and workflows within the organization.&lt;/p&gt;

&lt;p&gt;As I moved on to my next fully remote role at &lt;a href="https://gatsbyjs.com" rel="noopener noreferrer"&gt;Gatsby&lt;/a&gt;, I found areas where I could — ostensibly — meaningfully contribute to the internal tooling ecosystem myself. And indeed, if I ever took on a role that was not Developer Relations in the future, an internal dev tools team is the first place I could see myself being very happy.&lt;/p&gt;

&lt;h1&gt;
  
  
  Rota: What is the Task at Hand?
&lt;/h1&gt;

&lt;p&gt;At many tech companies, teams have a need for regularly staffed &lt;em&gt;rotations&lt;/em&gt;. Rota exists to &lt;em&gt;help manage rotations&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;For example, perhaps a content team needs blog post drafts to be reviewed each week. It doesn't make sense for one person to be responsible for this all the time, so instead the responsibility is shared among team members with one person reviewing each week. Perhaps an OSS organization has issues that need triage or pull requests that need review; these tasks also rotate amongst team members.&lt;/p&gt;

&lt;p&gt;Maybe someone outside the rotation needs to contact whoever is currently on-call for a rotated task, but they don't know at any given time &lt;em&gt;who&lt;/em&gt; to reach out to. They could go look up names on a list or a calendar, or they could blast out a message to the entire Slack channel, or use a &lt;code&gt;@usergroup&lt;/code&gt; that notifies everyone on the team, but this is &lt;em&gt;unscalable&lt;/em&gt; and &lt;em&gt;highly disruptive&lt;/em&gt;, especially as a company grows.&lt;/p&gt;

&lt;h1&gt;
  
  
  Rota In Action
&lt;/h1&gt;

&lt;p&gt;Using Rota, we can set up new rotations, staff them, assign people to be on call, rotate the assignment, and send messages to whoever is currently staffing any given rotation.&lt;/p&gt;

&lt;p&gt;You can create, name, and describe new rotations:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lh9cgzq1e6mv6iwil6a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lh9cgzq1e6mv6iwil6a.png" alt="create a new rotation with a simple " width="800" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can then assign a "staff list" (usernames of everyone who should take part in the rotation, in assigning order):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmrsv0tth0147x9l95i3m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmrsv0tth0147x9l95i3m.png" alt="add a staff list to an existing rotation" width="800" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then you can assign someone to the rotation either by username, or by assigning the &lt;code&gt;next&lt;/code&gt; user on staff. When assigning the rotation, you can also pass an optional handoff message:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx8zurbgfkto8tnkf4o78.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx8zurbgfkto8tnkf4o78.png" alt="assign the next person in the rotation and send them a handoff message" width="800" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The handoff message is then delivered to the new assignee in a direct message from &lt;code&gt;@rota&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkhzg65ay197abyi5p096.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkhzg65ay197abyi5p096.png" alt="dm from Rota with handoff message" width="800" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If anyone needs to contact the person who is on-call for any existing rotation, they can easily do so without needing to know &lt;em&gt;who&lt;/em&gt; is currently assigned.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ywqw0hqt73clnd5sfz1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ywqw0hqt73clnd5sfz1.png" alt="urgent message for the rotation" width="800" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The assigned user then receives a DM from &lt;code&gt;@rota&lt;/code&gt; notifying them of the message that needs their attention:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq2fta401ickg4k9gzdj2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq2fta401ickg4k9gzdj2.png" alt="DM received from message for on-call rotation user" width="800" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Rota Commands
&lt;/h1&gt;

&lt;p&gt;At the time of this writing, Rota supports the following commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@rota new "[new-rotation-name]" [description]&lt;/code&gt; creates a new rotation; rotation names can contain only lowercase letters, numbers, and hyphens. Technically the description is optional, but everyone will benefit if you provide one.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@rota delete "[rotation]"&lt;/code&gt; deletes the rotation completely (use with caution!).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@rota "[rotation]" description [new description]&lt;/code&gt; updates the description for a rotation.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@rota "[rotation]" staff [@user1 @user2 @user3]&lt;/code&gt; adds staff to a rotation; a space-separated list of usernames is expected as a parameter with usernames in the order of desired rotation (rotations with a staff list can be assigned using &lt;code&gt;assign next&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@rota "[rotation]" reset staff&lt;/code&gt; clears a rotation's staff list (use with caution!).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@rota "[rotation]" assign [@user] [optional handoff message]&lt;/code&gt; assigns someone to the rotation and, optionally, sends a DM to them with handoff information.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@rota "[rotation]" assign next [optional handoff message]&lt;/code&gt; assigns the next person in the staff list to a rotation and, optionally, sends a DM to them with handoff information.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@rota "[rotation]" unassign&lt;/code&gt; removes the current user assignment for a rotation.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@rota "[rotation]" who&lt;/code&gt; reports the name of a rotation's assigned user.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@rota "[rotation]" about&lt;/code&gt; displays the rotation's description and on-call user publicly, and displays the staff list only to the user who issued the commend (this is to prevent excessive notifications for everyone on staff).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@rota "[rotation]" [message]&lt;/code&gt; sends a direct message to the on-call user for the rotation, notifying them that your message needs attention.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@rota list&lt;/code&gt; displays a list of all currently known rotations.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@rota help&lt;/code&gt; shows how to use the bot.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; More commands may be added as development evolves and progresses over time. Visit the &lt;a href="https://github.com/kmaida/rota-slackbot" rel="noopener noreferrer"&gt;rota-slackbot GitHub repo&lt;/a&gt; for any updates.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Want to Use Rota?
&lt;/h1&gt;

&lt;p&gt;Rota is &lt;strong&gt;&lt;em&gt;free&lt;/em&gt; and &lt;em&gt;open source&lt;/em&gt;&lt;/strong&gt;. Its source code is available &lt;a href="https://github.com/kmaida/rota-slackbot" rel="noopener noreferrer"&gt;on GitHub at &lt;strong&gt;kmaida/rota-slackbot&lt;/strong&gt;&lt;/a&gt;, along with instructions for setting the app up in your own Slack workspace. &lt;a href="https://github.com/kmaida/rota-slackbot/blob/master/README.md" rel="noopener noreferrer"&gt;Rota's README&lt;/a&gt; lists the &lt;a href="https://github.com/kmaida/rota-slackbot/blob/master/README.md#commands" rel="noopener noreferrer"&gt;&lt;strong&gt;commands&lt;/strong&gt; that Rota supports&lt;/a&gt;, as well as &lt;strong&gt;tips for using Rota&lt;/strong&gt; with other Slack features (&lt;a href="https://github.com/kmaida/rota-slackbot/blob/master/README.md#rotation-reminders" rel="noopener noreferrer"&gt;like reminders&lt;/a&gt;) and third party apps (like &lt;a href="https://www.gator.works/" rel="noopener noreferrer"&gt;Gator&lt;/a&gt;, for &lt;a href="https://github.com/kmaida/rota-slackbot/blob/master/README.md#scheduling-messages" rel="noopener noreferrer"&gt;scheduling messages&lt;/a&gt;). Rota was developed for internal team use at &lt;a href="https://gatsbyjs.com" rel="noopener noreferrer"&gt;Gatsby&lt;/a&gt;, so it has been tested for that purpose and its continued development will focus on &lt;em&gt;internal tooling benefits&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Important Technical Details
&lt;/h2&gt;

&lt;p&gt;Because Rota is free, it is &lt;em&gt;not distributed&lt;/em&gt; in a way that allows you to go to the Slack app directory and install it from the marketplace. It needs to have &lt;a href="https://github.com/kmaida/rota-slackbot/blob/master/README.md#development" rel="noopener noreferrer"&gt;settings for your workspace&lt;/a&gt;, needs to have &lt;a href="https://github.com/kmaida/rota-slackbot/blob/master/README.md#database-setup" rel="noopener noreferrer"&gt;a database specific to your workspace&lt;/a&gt;, and also needs to be &lt;a href="https://github.com/kmaida/rota-slackbot/blob/master/README.md#deployment" rel="noopener noreferrer"&gt;deployed to your hosting&lt;/a&gt;. Detailed instructions for all of the above are provided in the repo's README.&lt;/p&gt;

&lt;p&gt;If I were to distribute Rota publicly, &lt;em&gt;it would not be possible for the app to remain free&lt;/em&gt;. Public distribution would require provisioning data stores for each workspace it is installed in and would significantly increase hosting costs and maintenance overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maintenance and Contribution
&lt;/h2&gt;

&lt;p&gt;I will be actively maintaining &lt;a href="https://github.com/kmaida/rota-slackbot" rel="noopener noreferrer"&gt;rota-slackbot&lt;/a&gt; at Gatsby during my tenure, as long as the bot is being actively used internally. If you'd like to aid in development work with Rota, please fork it on GitHub. To set expectations: because Rota is purpose-built for a specific organization, feature requests will be addressed if they have significant value add. &lt;em&gt;Community contributions&lt;/em&gt; to the codebase are welcome.&lt;/p&gt;

&lt;h1&gt;
  
  
  Thank You!
&lt;/h1&gt;

&lt;p&gt;I had a great time building Rota, and my hope is that it helps internally at my organization, but also that it helps others who share similar challenges in their teams and companies elsewhere. 🎉&lt;/p&gt;

</description>
      <category>slack</category>
      <category>remote</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>The Developer Relations Explainer</title>
      <dc:creator>Kim Maida</dc:creator>
      <pubDate>Sun, 10 May 2020 04:07:17 +0000</pubDate>
      <link>https://dev.to/kimmaida/the-developer-relations-explainer-431o</link>
      <guid>https://dev.to/kimmaida/the-developer-relations-explainer-431o</guid>
      <description>&lt;p&gt;The goal of this article is to provide an explainer sharing my thoughts on what Developer Relations is, what its core tenets are, and what important questions DevRel works to provide answers to.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Four Houses of Developer Relations
&lt;/h1&gt;

&lt;p&gt;Developer Relations, or "DevRel," is a field in technology whose practitioners focus on improving and nurturing the relationship that an entity (be it a commercial product company, an open source organization, a platform, or other type of technology offering) shares with its developer users.&lt;/p&gt;

&lt;p&gt;There are many different roles within Developer Relations. These include titles like Developer Advocate, Developer Evangelist, Community Manager, Developer Programs Manager, and more. There are several areas of DevRel which I see as equally important "houses" that make up the greater Developer Relations ecosystem. &lt;strong&gt;In order for a Developer Relations team to be successful and productive, all four of the following houses should play a part in the greater whole.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer Advocacy
&lt;/h2&gt;

&lt;p&gt;Developer advocacy focuses on championing the developer users and representing their interests and input both externally and internally.&lt;/p&gt;

&lt;p&gt;The job titles "Developer Advocate" and "Developer Evangelist" are often used interchangeably in the industry. In terms of &lt;em&gt;practice&lt;/em&gt;, advocacy and evangelism are not identical — and both are important aspects of Developer Relations. In fact, most DevRel folks who hold a title of either "Developer Advocate" or "Developer Evangelist" actually do both advocacy &lt;em&gt;and&lt;/em&gt; evangelism in their day-to-day job.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"A Developer Advocate’s job is to cultivate trust from both the product and the developers they represent by reaching across the table, listening, trying things for themselves, and understanding context and roadmaps."&lt;/em&gt; –&lt;a href="https://medium.com/@ashleymcnamara/what-is-developer-advocacy-3a92442b627c" rel="noopener noreferrer"&gt;Ashley McNamara&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Developer advocacy is centered around advocating &lt;em&gt;on behalf of the developer user to the company&lt;/em&gt;. Some of the primary traits necessary for practicing effective developer advocacy are &lt;em&gt;user empathy&lt;/em&gt; and &lt;em&gt;emotional intelligence&lt;/em&gt;. When it comes to products whose primary users are developers, being able to understand the developer's point of view and communicate user feedback effectively to make change in the product is key.&lt;/p&gt;

&lt;p&gt;Developer advocacy is about taking on the lion's share of the responsibility to reach out to the developer user community, help bring forward appropriate messaging, training and resources, and elevate the voices of the community both publicly and also inside the company. &lt;/p&gt;

&lt;h2&gt;
  
  
  Developer Evangelism
&lt;/h2&gt;

&lt;p&gt;Etymologically, the word "evangelism" arises from the Greek "εὐαγγελίζεσθαι" (&lt;em&gt;euangelizesthai&lt;/em&gt;): to preach the gospel / to spread the good word.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"A developer evangelist is a spokesperson, mediator and translator between a company and both its technical staff and outside developers."&lt;/em&gt; –&lt;a href="http://developer-evangelism.com/" rel="noopener noreferrer"&gt;Christian Heilmann&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Developer evangelism centers around representing an organization and demonstrating what benefits the organization's offerings have for developers. How does the product solve problems and help developers get the job done? They speak, engage, and instruct on behalf of the company to share how the products and services can better help developers to accomplish things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer Experience
&lt;/h2&gt;

&lt;p&gt;Developer Experience is about cultivating, enhancing, and supporting a delightful experience for the developers who are using a software product, effectively using knowledge, research, and creativity to solve challenges and make improvements.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Developer Experience (DX) is the equivalent to User Experience (UX) when the user of the software or system is a developer."&lt;/em&gt; –&lt;a href="https://hackernoon.com/the-best-practices-for-a-great-developer-experience-dx-9036834382b0" rel="noopener noreferrer"&gt;Sam Jarman&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;DX can mean many things at different companies. For an open source organization, a significant portion of the developer experience may focus on OSS contributors in the community. How are they supported when they submit issues and pull requests? How can they get access to resources and guidance to make meaningful contributions? DX also includes enablement of a developer's learning journey with a product. Are there helpful materials and tutorials available to pave their path to success with the product?&lt;/p&gt;

&lt;p&gt;DX can also include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tools and dashboard interfaces&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;li&gt;Tutorials and demos&lt;/li&gt;
&lt;li&gt;Onboarding experiences&lt;/li&gt;
&lt;li&gt;Avenues for getting developer support&lt;/li&gt;
&lt;li&gt;Ways for developers to provide product feedback&lt;/li&gt;
&lt;li&gt;Transparency around public product roadmaps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...and much more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Community
&lt;/h2&gt;

&lt;p&gt;Community refers to the current users and also &lt;em&gt;potential&lt;/em&gt; users of a software or technology. This includes everyone from students and people just learning to code to senior architects to internal employees. Anyone who uses a technology, talks about it, advocates for it, provides feedback on it, etc. is a member of that technology or organization's developer community.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Community includes a company’s employees (at the very least, the relevant product division), current customers, as well as prospects, and anyone who could in the future be interested in using the product… which is a fairly broad group of people."&lt;/em&gt; –&lt;a href="https://www.marythengvall.com/blog/2019/5/22/what-is-developer-relations-and-why-should-you-care" rel="noopener noreferrer"&gt;Mary Thengvall&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Community is about bolstering, nurturing, and cultivating the developer community with &lt;em&gt;compassion&lt;/em&gt; and &lt;em&gt;governing&lt;/em&gt; its interactions fairly.&lt;/p&gt;

&lt;h1&gt;
  
  
  Developer Relations Asks These Questions
&lt;/h1&gt;

&lt;p&gt;When working in Developer Relations, we should be seeking to provide answers to two variants of three questions:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. 💁🏽‍♀️ How can we &lt;strong&gt;help&lt;/strong&gt;?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How can we help &lt;em&gt;the developer community&lt;/em&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We do this in many ways, and are always on the lookout for more ways to do so. Some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating content resources (e.g., giving talks at events, writing blog posts, producing videos, courses, livestreams, etc.)&lt;/li&gt;
&lt;li&gt;Answering questions (e.g., staffing forums, Twitter and social media, responding to direct outreach, reaching out to the community to find out what questions developers have, etc.)&lt;/li&gt;
&lt;li&gt;Supporting developers who wish to provide their own resources (e.g., sharing important messaging, offering content creator training, supporting meetups and events run by the community, connecting content creators with internal subject matter experts, holding office hours, offering paired programming sessions, etc.)&lt;/li&gt;
&lt;li&gt;Requesting, receiving, and aggregating feedback from the community and championing that feedback within the company to improve the product&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How can we help &lt;em&gt;our organization&lt;/em&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The same question should be asked from the perspective of the organization we work for. Ways we can use our position in Developer Relations to help our org include (but are not limited to):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Establishing developer feedback channels and managing communication to ensure that feedback is appropriately delivered and acted upon by teams within the org (such as Product, Engineering, Documentation, Design, etc.)&lt;/li&gt;
&lt;li&gt;Supporting feature launches with community engagement, content, and proactive anticipation of community responses&lt;/li&gt;
&lt;li&gt;Providing internal resources and opportunities for fellow employees to get involved with employee advocacy&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. ⚔️ What challenges can we &lt;strong&gt;resolve&lt;/strong&gt;?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What challenges can we resolve &lt;em&gt;for the developer community&lt;/em&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Developer Relations teams should also be strongly focused on problem-solving, identifying challenges, and crafting sustainable solutions. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do developers have a clear path and good experience contributing to open source?&lt;/li&gt;
&lt;li&gt;Are developers confused about the way features of the product work, and can resources be provided to clarify?&lt;/li&gt;
&lt;li&gt;Is community feedback received and followed up on appropriately and do community members know their input is valued?&lt;/li&gt;
&lt;li&gt;Are there ample resources for developers with all different levels of experience to work productively with the software or platform?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What challenges can we resolve &lt;em&gt;for the organization&lt;/em&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Within an organization, there are many ways Developer Relations can create and improve processes, set up new workflows, and collaborate cross-functionally across teams and departments, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are teams in the company communicating effectively with each other to ensure that developers receive the best experience possible? (E.g., is marketing aligned with product and engineering?)&lt;/li&gt;
&lt;li&gt;If the organization has a focus on open source, how are issues and PRs triaged efficiently and sustainably without overloading any single team?&lt;/li&gt;
&lt;li&gt;Is there strong messaging around the organization's goals and purpose, and how can this messaging be amplified to and &lt;em&gt;by&lt;/em&gt; the community?&lt;/li&gt;
&lt;li&gt;Do teams within the organization feel confident that they are connected to and aware of important feedback and sentiments of developers who use the product?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. 🧰 What can we &lt;strong&gt;build&lt;/strong&gt;?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What can we build &lt;em&gt;for the developer community&lt;/em&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Developer Relations also has a responsibility to &lt;em&gt;create&lt;/em&gt; and &lt;em&gt;build&lt;/em&gt;. In doing so, we provide platforms to elevate community voices and to offer opportunities to developers. We can build things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ambassador programs to mentor, support, and grow community members who are interested in spreading the word about a technology offering&lt;/li&gt;
&lt;li&gt;Community platforms such as forums, real-time chats, user mailing lists, and more&lt;/li&gt;
&lt;li&gt;Demos, samples, tutorials, guides, showcases, and more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What can we build &lt;em&gt;for the organization&lt;/em&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Within the organization, we can also build internal tooling, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Programs for beta testing, early access, and community advisory groups to bring actionable and &lt;em&gt;early&lt;/em&gt; feedback into the company&lt;/li&gt;
&lt;li&gt;Workflows and dashboards to track community sentiment and growth&lt;/li&gt;
&lt;li&gt;Apps and automated tooling to manage community programs, incentives, swag, event support requests, etc.&lt;/li&gt;
&lt;li&gt;Bots and API integrations to support moderation, contributor assistance, metrics, frequently asked questions, and more&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  It's About Making a Difference
&lt;/h1&gt;

&lt;p&gt;Developer Relations team members work on a myriad of different problems and tasks, and face unique challenges to craft creative and remarkable solutions. DevRel is exciting because it's different across every organization: it is so intrinsically tied to that organization's technology, audience, goals, and area of focus. You will never do the &lt;em&gt;same&lt;/em&gt; DevRel job twice at two different companies — though the underlying traits and overall thematic elements will remain consistent. Much of this boils down to answering one question (albeit with lots of variation and nuance): &lt;em&gt;How can I help?&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Do You Want a Job in Developer Relations?
&lt;/h2&gt;

&lt;p&gt;If you're interested in working in DevRel, I would encourage you to do it because &lt;em&gt;you want to help&lt;/em&gt; — not &lt;em&gt;solely&lt;/em&gt; for personal glory or to become &lt;em&gt;industry-famous&lt;/em&gt;. A great DevRel team member is a champion for the developer, the organization, the community, and the user experience. Compassion, kindness, and empathy are truly valuable skills for anyone interested in Developer Relations. If you don't come at it with a deep caring for the success of others, the early sense of fulfillment from fame-and-glory will fizzle out quickly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;As a developer marketing leader, my job is to &lt;strong&gt;design and engineer the vehicle that drives the voices of others forward&lt;/strong&gt;. I am not the racecar driver who crosses the finish line and is rewarded with a wreath and a trophy; I'm the unseen engineer who makes sure the racecar has been built to operate in the most performant and high quality manner that it can. Developer Advocates often get to build their personal brand in a big way; but leading DevRel frequently means being comfortable and feeling fulfilled from behind the scenes.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'd love to share thoughts and tips on how to get started landing a job in DevRel, but that's a blog post for another day. 🙂&lt;/p&gt;

</description>
      <category>devrel</category>
      <category>community</category>
      <category>career</category>
    </item>
  </channel>
</rss>
