<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Authorization on Model Context Protocol Blog</title><link>https://blog.modelcontextprotocol.io/tags/authorization/</link><description>Recent content in Authorization on Model Context Protocol Blog</description><image><title>Model Context Protocol Blog</title><url>https://blog.modelcontextprotocol.io/og-image.png</url><link>https://blog.modelcontextprotocol.io/og-image.png</link></image><generator>Hugo -- 0.148.0</generator><language>en-us</language><copyright>Copyright © Model Context Protocol a Series of LF Projects, LLC.
For web site terms of use, trademark policy and other project policies please see https://lfprojects.org.</copyright><lastBuildDate>Wed, 24 Jun 2026 08:46:31 -0700</lastBuildDate><atom:link href="https://blog.modelcontextprotocol.io/tags/authorization/index.xml" rel="self" type="application/rss+xml"/><item><title>Enterprise-Managed Authorization: Zero-touch OAuth for MCP</title><link>https://blog.modelcontextprotocol.io/posts/enterprise-managed-auth/</link><pubDate>Thu, 18 Jun 2026 17:00:00 +0000</pubDate><guid>https://blog.modelcontextprotocol.io/posts/enterprise-managed-auth/</guid><description>The Enterprise-Managed Authorization extension to the Model Context Protocol is now stable, enabling organizations to centrally provision MCP server access through their identity provider so users get connected servers on first login without per-app OAuth.</description><content:encoded><![CDATA[<p><em>The Enterprise-Managed Authorization extension is now stable. Organizations can centrally
manage authorization for MCP servers and end-users can access all connected MCP servers
through a single log in. The extension is being adopted by Anthropic, Microsoft, Okta and
a growing number of MCP servers.</em></p>
<p>The <a href="https://modelcontextprotocol.io/extensions/auth/enterprise-managed-authorization">Enterprise-Managed Authorization (EMA) extension</a>
is now stable. We&rsquo;ve heard from the community that authorization and repeated consent
prompts from connected MCP servers is one of the biggest pain points when it comes to
managing connectivity in enterprise environments. This extension helps address this.</p>
<p>EMA allows organizations to control MCP server access centrally through their trusted
identity provider. For end-users, this means a zero-touch setup: the MCP servers they
need are connected on first login, with no per-app OAuth and nothing to configure as a
one-off.</p>
<p><img alt="Standard MCP authorization requires authenticating to every server one by one. Enterprise-Managed Authorization authenticates once through your identity provider and every server the admin authorized connects automatically, scoped to the user&rsquo;s groups and roles." loading="lazy" src="/posts/enterprise-managed-auth/ema-comparison.png"></p>
<h2 id="per-user-auth-is-high-friction">Per-user auth is high friction</h2>
<p>The standard MCP authorization model was designed to be user-scoped and bound to the
traditional interactive auth conventions. While this might work well for more general
consumer scenarios where individuals decide what touches their data, this doesn&rsquo;t quite
scale for enterprise deployments:</p>
<ul>
<li><strong>Every employee has to authorize every server individually</strong>: onboarding means
manually connecting service after service.</li>
<li><strong>Security teams cannot enforce consistent policy</strong>: access is whatever each user
authorized, with no central control or audit trail.</li>
<li><strong>Work and personal accounts blur together</strong>: there&rsquo;s no way to require a corporate
identity, so a user can connect a personal account to a work tool.</li>
</ul>
<p>This combination of factors slows MCP adoption and pushes people toward brittle
workarounds. With no universal standard for preserving shared auth state, everyone
invents their own bespoke solution. The data and tools are available, but the per-user
authorization tax keeps most of them switched off.</p>
<h2 id="authorize-once-inherit-everywhere">Authorize once, inherit everywhere</h2>
<p><a href="https://modelcontextprotocol.io/extensions/auth/enterprise-managed-authorization">Enterprise-Managed Authorization</a>
makes the organization&rsquo;s IdP the authoritative decision-maker for MCP server access.
Administrators define the policy once and users can authenticate with their existing
identity into the MCP host. The IdP can grant or deny access based on group membership,
role, and conditional access rules.</p>
<p>Under the hood, the client obtains an
<a href="https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-assertion-authz-grant/">Identity Assertion JWT Authorization Grant (ID-JAG)</a>
from the IdP during single sign-on and exchanges it for an access token from the MCP
server&rsquo;s authorization server. The user is never redirected through a per-server consent
screen. Three properties fall out of that flow:</p>
<ul>
<li><strong>Authorize once, inherit everywhere:</strong> admins enable a server for the org. Users get
it automatically, scoped to the groups and roles they already have.</li>
<li><strong>Centralized policy and audit:</strong> access decisions live in the IdP admin console, with
one auditable trail across every connector.</li>
<li><strong>Removing personal/enterprise mixups:</strong> by removing the interactive account selection
step, it&rsquo;s much easier to prevent data flowing between personal and enterprise accounts
by mistake or compromise.</li>
</ul>
<p>We see this as a brand new baseline for MCP in the enterprise. When users log in, their
client should be connected to the tools and data they&rsquo;re authorized to use with no extra
steps in between.</p>
<h2 id="early-adopters">Early adopters</h2>
<p>This launch brought together three groups that collaborated closely on making the
implementation real:</p>
<ul>
<li><strong>Identity providers:</strong> Okta is the first supported identity provider. Organizations
using Okta can provision MCP access to supported servers through any supported client,
using
<a href="https://www.okta.com/identity-101/cross-app-access-securing-ai-agent-and-app-to-app-connections/">Okta&rsquo;s Cross App Access (XAA)</a>.</li>
<li><strong>Clients:</strong>
<a href="https://claude.com/blog/enterprise-managed-auth">Anthropic has implemented the extension</a>
in its shared MCP layer for Claude. Admins can authorize MCP servers for users across
Claude, Claude Code, and Cowork. Additionally,
<a href="https://code.visualstudio.com/updates/v1_123#_enterprise-managed-mcp-authentication-preview">Visual Studio Code has also added support</a>
for EMA right in the IDE.</li>
<li><strong>Servers:</strong> Asana, Atlassian, Canva, Figma, Granola, Linear and Supabase now support
EMA, with Slack and more actively adding support.</li>
</ul>
<p>We&rsquo;re excited for more identity providers, clients, and servers to adopt
Enterprise-Managed Auth to help reduce the authorization-related fatigue and
significantly improve the security and observability posture for its implementers.</p>
<blockquote>
<p>&ldquo;The momentum around MCP is incredible, but as we move toward an interconnected AI
workforce, security can&rsquo;t be an afterthought. By embedding the Cross App Access protocol
into MCP as the Enterprise-Managed Authorization extension, we turn identity into a
centralized governance plane and give security teams strict compliance control and users
a seamless, secure experience.&rdquo;</p>
<p>— <strong>Aaron Parecki, Director of Identity Standards, Okta</strong></p></blockquote>
<blockquote>
<p>&ldquo;The Figma MCP brings the power of code and canvas together so teams can move faster,
explore more and ship products that stand out. As MCP adoption grows, XAA makes it
easier for enterprises to scale their MCP deployments securely without slowing teams
down.&rdquo;</p>
<p>— <strong>Devdatta Akhawe, VP of Engineering, Figma</strong></p></blockquote>
<blockquote>
<p>&ldquo;Logging in once and automatically having all your MCP connectors automatically setup is
pretty magical.&rdquo;</p>
<p>— <strong>Tom Moor, Head of Engineering, Linear</strong></p></blockquote>
<h2 id="get-involved">Get involved</h2>
<p>As with all other MCP extensions, features, and enhancements, we welcome your input.
We&rsquo;re encouraging clients, servers, and identity platforms to review the extension
specification and add support for the new standard into their products:</p>
<ul>
<li><strong>Read the requirements:</strong> the
<a href="https://modelcontextprotocol.io/extensions/auth/enterprise-managed-authorization">Enterprise-Managed Authorization page</a>
documents the flow for clients, servers, and authorization servers.</li>
<li><strong>Source and spec:</strong> see the
<a href="https://github.com/modelcontextprotocol/ext-auth">ext-auth repository</a> and the
<a href="https://github.com/modelcontextprotocol/ext-auth/blob/main/specification/stable/enterprise-managed-authorization.mdx">specification</a>
for the latest in EMA evolution as well as any support materials that will help you get
started.</li>
</ul>
<p>If you&rsquo;re interested in discussing the extension, sharing compatibility reports, or
iterating on the extension, join the
<a href="https://modelcontextprotocol.io/community/interest-groups/enterprise-managed-authorization">EMA Interest Group</a>.</p>
<h2 id="acknowledgements">Acknowledgements</h2>
<p>Enterprise-Managed Authorization is the work of the MCP community: the authors of
SEP-990, the maintainers of the
<a href="https://github.com/modelcontextprotocol/ext-auth">ext-auth repository</a>, and the identity
and MCP providers
who tested early implementations and pushed the spec forward. Thank you to everyone who
contributed.</p>
]]></content:encoded></item><item><title>Evolving OAuth Client Registration in the Model Context Protocol</title><link>https://blog.modelcontextprotocol.io/posts/client_registration/</link><pubDate>Fri, 22 Aug 2025 10:00:00 +0000</pubDate><guid>https://blog.modelcontextprotocol.io/posts/client_registration/</guid><description>&lt;p>The Model Context Protocol (MCP) has adopted OAuth 2.1 as the foundation for its authorization framework. A key part of the authorization flow that MCP is particularly reliant on is &lt;strong>client registration&lt;/strong>.&lt;/p>
&lt;p>This is especially important in a world where clients and servers don&amp;rsquo;t have a pre-existing relationship - we can&amp;rsquo;t assume that we will always know which MCP clients will connect to which MCP servers. This design highlights two challenges that need to be addressed:&lt;/p></description><content:encoded><![CDATA[<p>The Model Context Protocol (MCP) has adopted OAuth 2.1 as the foundation for its authorization framework. A key part of the authorization flow that MCP is particularly reliant on is <strong>client registration</strong>.</p>
<p>This is especially important in a world where clients and servers don&rsquo;t have a pre-existing relationship - we can&rsquo;t assume that we will always know which MCP clients will connect to which MCP servers. This design highlights two challenges that need to be addressed:</p>
<ul>
<li>Operational issues with managing client IDs via <a href="https://datatracker.ietf.org/doc/html/rfc7591">Dynamic Client Registration</a> (DCR)</li>
<li>Preventing client impersonation</li>
</ul>
<p>If you&rsquo;re already familiar with OAuth and the current state of client registration in MCP, skip to <a href="#two-distinct-challenges-in-mcp-client-registration">Two Distinct Challenges in MCP Client Registration</a>.</p>
<h2 id="background-on-oauth">Background on OAuth</h2>
<p>A protected MCP server that implements OAuth 2.1 should allow a user to grant a client access to itself and prevent attempts to trick the user into granting access to a client they didn&rsquo;t intend to use via phishing.</p>
<p>The authorization flow can be best described by looking at this sequence diagram:</p>
<pre class="mermaid">
  sequenceDiagram
   participant Client
   participant User
   participant AuthServer as Authorization Server
   participant Resource as Resource Server

   Client-&gt;&gt;User: 1. Redirect to authorization server
   User-&gt;&gt;AuthServer: Navigate to auth URL
   AuthServer-&gt;&gt;User: 2. Display consent screen
   User-&gt;&gt;AuthServer: Approve access
   AuthServer-&gt;&gt;Client: 3. Redirect with authorization code
   Client-&gt;&gt;AuthServer: 4. Exchange code for access token
   AuthServer--&gt;&gt;Client: Access token (saved)
   Client-&gt;&gt;Resource: 5. Request with access token
   Resource--&gt;&gt;Client: Protected resource
</pre>
<p>This flow requires a few steps to be performed to acquire an access token:</p>
<ol>
<li>The client directs the user to an authorization UI provided by the authorization server</li>
<li>The authorization server displays a consent screen to the user</li>
<li>User approves client access and the authorization server redirects the user back to the client with an access code</li>
<li>Client exchanges the access code for a set of tokens, which are cached locally</li>
<li>Client uses the access token to access the MCP server</li>
</ol>
<p>To be able to initiate this flow, however, the authorization server first needs some basic information about the client that is kicking off the authorization process:</p>
<ol>
<li><strong>Client name</strong>: Human readable text to display in the consent screen to help the user decide whether they want to grant access.</li>
<li><strong>Redirect URL</strong>: The destination to send the authorization code back to if the user consents.</li>
</ol>
<p>In order to prevent a malicious client from tricking a user into granting access they didn&rsquo;t intend to grant, the authorization server must be able to trust the client information it has.</p>
<p>For example, a malicious client could claim to be <code>Claude Desktop</code> on the consent screen while actually being owned by someone not affiliated with Claude Desktop developers. Seeing the client information on the consent screen, users might grant access thinking they&rsquo;re authorizing the legitimate Claude Desktop, not realizing that some malicious client now has access to their account.</p>
<h2 id="improving-client-registration-in-mcp">Improving Client Registration in MCP</h2>
<p>For MCP users, a common pattern is to connect to an MCP server by using its URL directly in an MCP client.</p>
<p>This goes against the typical OAuth authorization pattern because the user is selecting the resource server to connect to rather than the client developer. This problem is compounded by the fact that there is an unbounded number of authorization servers that an MCP server may use, meaning that clients need to be able to complete the authorization flow regardless of the provider used.</p>
<p>Some client developers have implemented pre-registration with a select few authorization servers. In this scenario, the client doesn&rsquo;t need to rely on DCR when it detects an authorization server it knows. However, this is a solution that doesn&rsquo;t scale given the breadth of the MCP ecosystem - it&rsquo;s impossible to have every client be registered with every authorization server there is.
To mitigate this challenge, we set out to outline some of the goals that we wanted to achieve with improving the client registration experience:</p>
<ol>
<li><strong>Clients</strong>: Client developers don&rsquo;t need to implement pre-registration and distribute a client ID for each authorization server MCP servers might be using.</li>
<li><strong>Users</strong>: Users don&rsquo;t need to go through a pre-registration process themselves and manually specify a client ID for every MCP server they connect to.</li>
<li><strong>Authorization servers</strong>:</li>
</ol>
<ul>
<li><strong>Trust in Metadata</strong>: Authorization servers have a way to trust the metadata they associate with a client, such as name and redirect URL.</li>
<li><strong>Single Client ID per App</strong>: Authorization servers can have a single client ID per client for governance and management purposes</li>
<li><strong>Selective Allow/Deny</strong>: Authorization servers can selectively allow or deny clients based on their policies.</li>
<li><strong>Database Management</strong>: Authorization servers do not need to handle an unbounded database or expiration flows for every new client registration.</li>
</ul>
<p>Currently, none of our existing client registration approaches satisfy all of these requirements. Pre-registration requires too much effort in a highly variable setting (unbounded number of clients connecting to unbounded number of servers), while DCR reduces effort but creates operational issues that a lot of the authorization servers are not ready to tackle yet.</p>
<h2 id="two-distinct-challenges-in-mcp-client-registration">Two Distinct Challenges in MCP Client Registration</h2>
<p>After extensive discussion with MCP server implementers, we&rsquo;ve identified that a few competing solutions to the registration problem were addressing two distinct issues:</p>
<ol>
<li><strong>Operational limitations</strong> of Dynamic Client Registration in open environments</li>
<li><strong>Client identity and impersonation</strong> risks across different deployment scenarios</li>
</ol>
<h2 id="challenge-1-operational-limitations-of-dynamic-client-registration"><strong>Challenge 1: Operational Limitations of Dynamic Client Registration</strong></h2>
<h3 id="the-dcr-model-mismatch"><strong>The DCR Model Mismatch</strong></h3>
<p>The DCR design takes the pre-registration pattern available in modern OAuth-based authorization servers and makes it available via an API. In fully open environments like MCP, DCR really puts the spotlight on a few operational challenges that an open registration endpoint introduces:</p>
<p><strong>For authorization servers:</strong></p>
<ul>
<li><strong>Unbounded database growth</strong>: Every time a user connects a client to an MCP server, a new registration is created with the authorization server unless the client already has one. Registrations are also not portable, so using Claude Desktop on your Windows machine, and then jumping to Claude Desktop on macOS will create two distinct client registrations.</li>
<li><strong>Client expiry &ldquo;black hole&rdquo;</strong>: There&rsquo;s no way to tell a client that its ID is invalid without creating an open redirect vulnerability. Clients have to implement their own heuristics for client ID management.</li>
<li><strong>Per-instance confusion</strong>: Each client instance typically gets its own client ID even when using the same application, but on different machines or across different users. From an auditing perspective, an authorization server administrator may see hundreds (if not thousands) of records for the same application without any rhyme or reason.</li>
<li><strong>Denial-of-Service vulnerability</strong>: An unauthenticated <code>/register</code> endpoint writes to a database within the authorization server, meaning that tenant admins now need to worry about rate limiting or policy controls (e.g., hosts allowed to register clients).</li>
</ul>
<p><strong>For clients:</strong></p>
<ul>
<li><strong>Extra overhead</strong>: Managing registration state and another secret beyond access/refresh tokens</li>
<li><strong>No validity checking</strong>: Can&rsquo;t verify if a client ID is still valid</li>
<li><strong>Unclear lifecycle</strong>: No guidance on when to re-register or update credentials</li>
</ul>
<h3 id="solution-client-id-metadata-documents-cimd"><strong>Solution: Client ID Metadata Documents (CIMD)</strong></h3>
<p>Client ID Metadata Documents (CIMD), described in <a href="https://www.ietf.org/archive/id/draft-parecki-oauth-client-id-metadata-document-03.html">OAuth Client ID Metadata Document</a> and implemented by Bluesky, elegantly sidestep these operational issues.</p>
<p>Instead of a registration step, clients use an HTTPS metadata URL as their client ID directly. The server fetches the metadata from the URL at authorization time:</p>
<pre class="mermaid">
  sequenceDiagram
   participant Client
   participant AuthServer
   participant MetadataURL

   Client-&gt;&gt;AuthServer: Authorization request (client_id=https://app.com/oauth.json)
   AuthServer-&gt;&gt;MetadataURL: GET https://app.com/oauth.json
   MetadataURL--&gt;&gt;AuthServer: {name: &#34;App&#34;, redirect_uris: [...]}
   AuthServer-&gt;&gt;Client: Show consent screen &amp; continue flow
</pre>
<p>This addresses all the operational issues:</p>
<ul>
<li><strong>No unbounded database growth</strong>: Servers fetch metadata on-demand (can cache for performance)</li>
<li><strong>No expiry management</strong>: The URL is the ID - it doesn&rsquo;t expire</li>
<li><strong>Natural per-app model</strong>: One URL per application, not per user</li>
<li><strong>No registration endpoint</strong>: No unauthenticated write operations</li>
</ul>
<p>The cost? Clients need to host a metadata document at an HTTPS URL. For web applications, this is trivial. For desktop applications, this typically means hosting on their backend infrastructure.</p>
<h2 id="challenge-2-client-identity-and-impersonation"><strong>Challenge 2: Client Identity and Impersonation</strong></h2>
<p>The second challenge is orthogonal to the DCR vs. CIMD debate - it&rsquo;s about trusting that a client is who it claims to be. This problem will exist regardless of how the registration process is implemented.</p>
<p>For web-based clients, trust is more straightforward, as we have an HTTPS domain that&rsquo;s tied to a certificate authority. For desktop clients, if the client can&rsquo;t offload its authorization to existing backend infrastructure, there is difficulty trusting the client is legitimate and unmodified.</p>
<h3 id="the-trust-spectrum">The Trust Spectrum</h3>
<p>We can map impersonation scenarios on two axes: attacker cost and mitigation complexity.</p>
<p><img alt="Mitigation Cost vs Attack Cost" loading="lazy" src="/posts/client_registration/mitigation-attack-cost.png"></p>
<p><strong>Low attacker cost/Low mitigation complexity: Domain-based attacks</strong></p>
<ul>
<li><strong>Attack</strong>: Register malicious callback URI and claim to be <code>Claude Desktop</code></li>
<li><strong>Cost</strong>: Trick user into clicking a link and consenting</li>
<li><strong>Mitigation</strong>:
<ul>
<li>Restrict trusted domains/URLs</li>
<li>Show warnings for unknown domains</li>
<li>Works with both DCR and CIMD</li>
</ul>
</li>
</ul>
<p><strong>Medium attacker cost/Medium mitigation complexity: <code>localhost</code> impersonation</strong></p>
<ul>
<li><strong>Attack</strong>: Run malicious app on <code>localhost:8080</code>, impersonate legitimate client</li>
<li><strong>Cost</strong>: Trick user into running a malicious application (plus consenting for that app to have data access)</li>
<li><strong>Problem</strong>: Desktop apps can&rsquo;t hold secrets, hard to prove identity</li>
</ul>
<p><strong>High attacker cost/High mitigation complexity: Platform-attested applications</strong></p>
<ul>
<li><strong>Attack</strong>: Get malicious client signed by a trusted authority</li>
<li><strong>Cost</strong>: Extremely high - requires compromising certification vendor processes</li>
<li><strong>Mitigation</strong>: platform system-level attestation (future work)</li>
</ul>
<h3 id="solution-software-statements-for-desktop-applications"><strong>Solution: Software Statements for Desktop Applications</strong></h3>
<p>To broadly solve the client impersonation for the middle tier as well as to prevent <code>localhost</code> impersonation we need signed software statements. Implementing this would require:</p>
<ol>
<li>Client hosts a JSON Web Key Set (JWKS) on their backend</li>
<li>Client authenticates the user through their own flow</li>
<li>The client-owned backend service issues a short-lived, signed JWT attesting to the client&rsquo;s identity</li>
<li>Client includes this JWT in the OAuth flow</li>
<li>Authorization server verifies the JWT against the trusted JWKS</li>
</ol>
<p>This dramatically raises the bar for client impersonation, as an attacker would need to:</p>
<ul>
<li>Compromise the client&rsquo;s backend infrastructure, or</li>
<li>Successfully impersonate the client&rsquo;s authentication flow</li>
</ul>
<p>Crucially, <strong>software statements work with both DCR and CIMD</strong>. They&rsquo;re not a competing solution - they&rsquo;re a complementary security layer.</p>
<h3 id="future-platform-level-attestation"><strong>Future: Platform-Level Attestation</strong></h3>
<p>The strongest protection would be platform-level attestation, e.g. having macOS, Windows, or Android attest that a piece of software is legitimate.</p>
<p>Having OS-level attestation would make client impersonation unreasonably expensive. While the exact way this ties into a software statement is yet to be prototyped, the general direction is threading platform-level application identity validation through to the OAuth flow.</p>
<h2 id="the-complementary-path-forward"><strong>The Complementary Path Forward</strong></h2>
<p>While we&rsquo;re looking at all available options, it&rsquo;s important to note that we&rsquo;re not choosing between solutions. We&rsquo;re exploring complementary approaches for distinct problems:</p>
<p><strong>For operational issues</strong>: We are looking at adding CIMD support in favor of DCR</p>
<ul>
<li>Keep DCR for backward compatibility</li>
<li>Recommend CIMD for new implementations</li>
<li>Both achieve the same authorization goal</li>
</ul>
<p><strong>For trust issues</strong>: Layering software statements on top</p>
<ul>
<li>Optional enhancement for both DCR and CIMD</li>
<li>Required only when <code>localhost</code> impersonation is a concern</li>
<li>Authorization servers choose their required trust level</li>
</ul>
<h2 id="security-considerations"><strong>Security Considerations</strong></h2>
<p>Both CIMD and software statements require authorization servers to make outbound HTTPS requests, potentially to untrusted domains. Implementations must:</p>
<ul>
<li>Prevent SSRF attacks by blocking internal network access</li>
<li>Implement timeouts and size limits</li>
<li>Consider caching strategies for performance</li>
<li>Validate response formats strictly</li>
</ul>
<p>If we adopt these approaches, we’ll need good best practices and SDK support to help avoid vulnerabilities and provide a easy path for implementors.</p>
<h2 id="next-steps"><strong>Next Steps</strong></h2>
<p>Discussions for these approaches are happening in the <a href="https://modelcontextprotocol.io/community/sep-guidelines">Specification Enhancement Proposals</a> (SEP):</p>
<ul>
<li><a href="https://github.com/modelcontextprotocol/specification/discussions/991">SEP-991: Client ID Metadata Documents</a></li>
<li><a href="https://github.com/modelcontextprotocol/specification/discussions/1032">SEP-1032: Software Statements with DCR</a></li>
</ul>
<p>Get involved: Join the conversation in <a href="https://discord.gg/6CSzBmMkjX">Discord</a> (the #auth-wg-client-registration channel) or comment on the SEPs directly.</p>
<p>A big thank to the following folks for help with this blog post: Den Delimarsky, Aaron Parecki, Geoff Goodman, Andrew Block, Pieter Kasselman, Abhishek Hingnikar, and Bobby Tiernay.</p>
]]></content:encoded></item></channel></rss>