<?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>Authentication on Mark Wolfe&#39;s Blog</title>
    <link>https://www.wolfe.id.au/tags/authentication/</link>
    <description>Recent content in Authentication on Mark Wolfe&#39;s Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Tue, 02 Dec 2025 08:55:22 +1000</lastBuildDate><atom:link href="https://www.wolfe.id.au/tags/authentication/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Why Connect RPC is a great choice for building APIs</title>
      <link>https://www.wolfe.id.au/2025/12/02/why-connect-rpc-is-a-great-choice-for-building-apis/</link>
      <pubDate>Tue, 02 Dec 2025 08:55:22 +1000</pubDate>
      
      <guid>https://www.wolfe.id.au/2025/12/02/why-connect-rpc-is-a-great-choice-for-building-apis/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://connectrpc.com/&#34;&gt;Connect RPC&lt;/a&gt; is a suite of libraries which enable you to build HTTP based APIs which are gRPC compatible. It provides a bridge between &lt;a href=&#34;https://grpc.io/&#34;&gt;gRPC&lt;/a&gt; and HTTP/1.1, letting you leverage HTTP/2&amp;rsquo;s multiplexing and performance benefits while still supporting HTTP/1.1 clients. This makes it a great solution for teams looking to get the performance benefits of gRPC, while maintaining broad client compatibility.&lt;/p&gt;
&lt;p&gt;HTTP/2&amp;rsquo;s multiplexing and binary framing make it significantly more efficient than HTTP/1.1, reducing latency and improving throughput. Connect RPC lets you harness these benefits while maintaining broad client compatibility for services that can&amp;rsquo;t yet support HTTP/2.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://connectrpc.com/">Connect RPC</a> is a suite of libraries which enable you to build HTTP based APIs which are gRPC compatible. It provides a bridge between <a href="https://grpc.io/">gRPC</a> and HTTP/1.1, letting you leverage HTTP/2&rsquo;s multiplexing and performance benefits while still supporting HTTP/1.1 clients. This makes it a great solution for teams looking to get the performance benefits of gRPC, while maintaining broad client compatibility.</p>
<p>HTTP/2&rsquo;s multiplexing and binary framing make it significantly more efficient than HTTP/1.1, reducing latency and improving throughput. Connect RPC lets you harness these benefits while maintaining broad client compatibility for services that can&rsquo;t yet support HTTP/2.</p>
<p>Connect RPC can be used to build both internal and external APIs, powering frontends, mobile apps, CLIs, agents and more. See the list of <a href="https://github.com/connectrpc">supported languages</a>.</p>
<h2 id="core-features">Core Features</h2>
<p>Connect RPC provides a number of features out of the box, such as:</p>
<ul>
<li><a href="https://connectrpc.com/docs/go/interceptors">Interceptors</a> which make it easy to extend Connect RPC and are used to add authentication, logging, metrics, tracing and retries.</li>
<li><a href="https://connectrpc.com/docs/go/serialization-and-compression">Serialization &amp; compression</a>, with pluggable serializers, and support for asymmetric compression reducing the amount of data that needs to be transmitted, or received.</li>
<li><a href="https://connectrpc.com/docs/go/errors">Error handling</a>, with a standard error format, with support for custom error codes to allow for more granular error handling.</li>
<li><a href="https://connectrpc.com/docs/go/observability">Observability</a>, with in built support for OpenTelemetry enabling you to easily add tracing, or metrics to your APIs.</li>
<li><a href="https://connectrpc.com/docs/go/streaming">Streaming</a>, which provides a very efficient way to push or pull data without polling.</li>
<li><a href="https://connectrpc.com/docs/protocol/#summary">Schemas</a>, which enable you to define and validate your API schemas, and generate code from them.</li>
<li><a href="https://connectrpc.com/docs/web/generating-code/#local-generation">Code generation</a> for <a href="https://go.dev">Go</a>, <a href="https://www.typescriptlang.org/">TypeScript</a>, <a href="https://kotlinlang.org/">Kotlin</a>, <a href="https://developer.apple.com/swift/">Swift</a> and <a href="https://www.java.com/en/">Java</a>.</li>
</ul>
<h2 id="ecosystem">Ecosystem</h2>
<p>In addition to these features, Connect RPC is built on top of the Buf ecosystem, which offers notable benefits:</p>
<ul>
<li><a href="https://buf.build/blog/connect-rpc-joins-cncf">Connect RPC joins CNCF</a>, entering the cloud-native ecosystem, which is great for the long term sustainability of the project.</li>
<li><a href="https://buf.build/product/bsr">Buf Schema Registry</a>, which is a great tool for managing, sharing and versioning your API schemas.</li>
<li><a href="https://buf.build/product/cli">Buf CLI</a>, a handy all in one tool for managing your APIs, generating code and linting.</li>
</ul>
<h2 id="recommended-interceptor-packages">Recommended Interceptor Packages</h2>
<p>Some handy Go packages that provide pre-built Connect RPC interceptors worth exploring or using as a starting point:</p>
<ul>
<li><a href="https://github.com/connectrpc/authn-go">authn-go</a>, provides a rebuilt authentication middleware library for Go. It works with any authentication scheme (including HTTP basic authentication, cookies, bearer tokens, and mutual TLS).</li>
<li><a href="https://github.com/connectrpc/validate-go">validate-go</a> provides a Connect RPC interceptor that takes the tedium out of data validation. This package is powered by <a href="https://github.com/bufbuild/protovalidate-go">protovalidate</a>
and the <a href="https://github.com/google/cel-spec">Common Expression Language</a>.</li>
<li><a href="https://github.com/mdigger/rpclog">rpclog</a> provides a structured logging interceptor for Connect RPC with support for both unary and streaming RPCs.</li>
</ul>
<h2 id="summary">Summary</h2>
<ol>
<li>
<p>Connect RPC provides a paved and well maintained path to building gRPC compatible APIs, while maintaining compatibility for HTTP/1.1 clients. This is invaluable for product teams that need to support multiple client types without building custom compatibility layers.</p>
</li>
<li>
<p>Using a mature library like Connect RPC, you get to benefit from all the prebuilt integrations, and the added capabilities of the Buf ecosystem. This makes publishing and consuming APIs a breeze.</p>
</li>
<li>
<p>Protobuf schemas, high performance serialisation and compression ensure you get robust and efficient APIs.</p>
</li>
</ol>
<h2 id="conclusion">Conclusion</h2>
<p>Connect RPC makes it easy to build high-performance, robust APIs with gRPC compatibility, while avoiding the complexity of building and maintaining custom compatibility layers.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Why OIDC?</title>
      <link>https://www.wolfe.id.au/2025/11/16/why-oidc/</link>
      <pubDate>Sun, 16 Nov 2025 08:55:22 +1000</pubDate>
      
      <guid>https://www.wolfe.id.au/2025/11/16/why-oidc/</guid>
      <description>&lt;p&gt;Over the last few years there has been a push away from using machine identity for continuous integration (CI) agents, or runners, and instead use a more targeted, least privileged approach to authentication and authorization. This is where &lt;a href=&#34;https://openid.net/developers/how-connect-works/&#34;&gt;OIDC (OpenID Connect)&lt;/a&gt; comes in, which is a method of authentication used to bridge between the CI provider and cloud services such as AWS, Azure, and Google Cloud.&lt;/p&gt;
&lt;p&gt;In this model the CI provider acts as an identity provider, issuing tokens to the CI runner/agent which include a set of claims identifying the owner, pipeline, workflow and job that is being executed. This is then used to authenticate with the cloud service, and access the resources that the pipeline, workflow and job require.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Over the last few years there has been a push away from using machine identity for continuous integration (CI) agents, or runners, and instead use a more targeted, least privileged approach to authentication and authorization. This is where <a href="https://openid.net/developers/how-connect-works/">OIDC (OpenID Connect)</a> comes in, which is a method of authentication used to bridge between the CI provider and cloud services such as AWS, Azure, and Google Cloud.</p>
<p>In this model the CI provider acts as an identity provider, issuing tokens to the CI runner/agent which include a set of claims identifying the owner, pipeline, workflow and job that is being executed. This is then used to authenticate with the cloud service, and access the resources that the pipeline, workflow and job require.</p>
<p>In simple terms, this is a form of trust delegation, where the CI provider is trusted by the cloud service to issue tokens on behalf of the owner, pipeline, workflow and job.</p>
<h2 id="how-oidc-works">How OIDC Works</h2>
<p>The OIDC trust delegation flow is as follows:</p>
<pre class="mermaid">sequenceDiagram
    participant CI as CI Provider&lt;br/&gt;(Identity Provider)
    participant Runner as CI Runner/Agent
    participant Cloud as Cloud Service&lt;br/&gt;(AWS/Azure/GCP)

    Note over CI,Cloud: OIDC Trust Delegation Flow

    CI-&gt;&gt;Runner: Issue OIDC token with claims&lt;br/&gt;(pipeline, workflow, job)
    Runner-&gt;&gt;Cloud: Request access with OIDC token
    Cloud-&gt;&gt;Cloud: Verify token signature&lt;br/&gt;and validate claims
    Cloud-&gt;&gt;Runner: Grant temporary credentials
    Runner-&gt;&gt;Cloud: Access resources with credentials

    Note over CI,Cloud: Trust established via OIDC configuration
</pre>
<p>There are a few things to note:</p>
<ul>
<li>When using OIDC, the runner doesn&rsquo;t need to be registered with the cloud service; it is granted access via the OIDC token.</li>
<li>The OIDC token is cryptographically signed by the CI provider, and the cloud service verifies the signature to ensure the token is valid.</li>
<li>In this model all three parties (CI provider, runner, and cloud service) are trusted to issue and verify tokens.</li>
</ul>
<h2 id="limiting-cloud-access-to-the-agentrunner">Limiting Cloud Access to the Agent/Runner</h2>
<p>To ensure the CI provider can&rsquo;t access the cloud service directly, you can add conditions which ensure only the runner/agent is allowed to access the cloud resources.</p>
<p>On top of this cloud providers such as AWS have conditions which can <a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-network-properties">restrict access to a specific AWS network resource, such as a VPC</a>. I recommend familiarizing yourself with the documentation for your cloud provider to understand how to lock down access to the runner/agent.</p>
<h2 id="benefits-of-oidc">Benefits of OIDC</h2>
<p>The reasons this is useful are:</p>
<ul>
<li>It provides a more secure and flexible approach to authentication and authorization</li>
<li>It limits the scope of the token to the specific pipeline, workflow, and job</li>
<li>It is tied to the lifecycle of the pipeline, workflow, and job, which means the token is limited to the duration of that execution</li>
<li>It is more flexible than using machine identity for CI runners/agents as it allows for more granular control over the permissions granted to the runner/agent</li>
</ul>
<h2 id="ephemeral-runnersagents">Ephemeral Runners/Agents</h2>
<p>Ephemeral runners/agents are short lived, single job, or single workflow runners/agents which are created before the workflow, or job is started. They provide a more secure and flexible approach to job execution as there is no need to worry about these environments being tainted by previous jobs or workflows.</p>
<p>When paired with OIDC these environments provide an extra layer of security as they are destroyed after the job or workflow is complete, further reducing the risk of cross job or workflow access.</p>
<h2 id="summary">Summary</h2>
<p>So in summary, OIDC provides a more secure and flexible approach to access management for CI projects, and it is particularly useful when paired with ephemeral runners/agents.</p>
<p>The biggest advantage of this approach is that it allows engineers to focus on the access required by the pipeline, workflow, and job, rather than having to manage machine identities and permissions for each runner/agent.</p>
<p>One of the interesting things about this approach is that you&rsquo;re not limited to using OIDC just with cloud providers; you can use it with your own services as well. By using OIDC libraries such as <a href="https://github.com/coreos/go-oidc">github.com/coreos/go-oidc</a>, you can implement APIs which can use the identity of CI pipelines, workflows, and jobs. An example of this is <a href="https://www.hashicorp.com/en/resources/using-oidc-with-hashicorp-vault-and-github-actions">Using OIDC With HashiCorp Vault and GitHub Actions</a>.</p>
<h2 id="links">Links</h2>
<ul>
<li><a href="https://buildkite.com/docs/pipelines/security/oidc">OIDC for Buildkite</a></li>
<li><a href="https://docs.github.com/en/enterprise-cloud@latest/actions/concepts/security/openid-connect">OIDC for GitHub Actions</a></li>
<li><a href="https://docs.gitlab.com/integration/openid_connect_provider/">OIDC for GitLab</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>Getting started with Cognito?</title>
      <link>https://www.wolfe.id.au/2019/12/16/getting-started-with-cognito/</link>
      <pubDate>Mon, 16 Dec 2019 10:46:00 +1000</pubDate>
      
      <guid>https://www.wolfe.id.au/2019/12/16/getting-started-with-cognito/</guid>
      <description>&lt;p&gt;The AWS &lt;a href=&#34;https://aws.amazon.com/cognito/&#34;&gt;Cognito&lt;/a&gt; product enables developers to build web or API based applications without worrying about authentication and authorisation.&lt;/p&gt;
&lt;p&gt;When setting up an applications authentication I try to keep in mind a few goals:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Keep my users data as safe as possible.&lt;/li&gt;
&lt;li&gt;Try and find something which is standards based, or supports integrating with standard protocols such as &lt;a href=&#34;https://openid.net/&#34;&gt;openid&lt;/a&gt;, &lt;a href=&#34;https://oauth.net/2/&#34;&gt;oauth2&lt;/a&gt; and &lt;a href=&#34;https://en.wikipedia.org/wiki/Security_Assertion_Markup_Language&#34;&gt;SAML&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Evaluate the authentication flows I need and avoid increasing scope and risk.&lt;/li&gt;
&lt;li&gt;Try to use a service to start with, or secondarily, an opensource project with a good security process and a healthy community.&lt;/li&gt;
&lt;li&gt;Limit any custom development to extensions, rather than throwing out the baby with the bath water.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As you can probably tell, my primary goal is to keep authentication out of my applications, I really don&amp;rsquo;t have the time or inclination to manage a handcrafted authentication solution.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>The AWS <a href="https://aws.amazon.com/cognito/">Cognito</a> product enables developers to build web or API based applications without worrying about authentication and authorisation.</p>
<p>When setting up an applications authentication I try to keep in mind a few goals:</p>
<ol>
<li>Keep my users data as safe as possible.</li>
<li>Try and find something which is standards based, or supports integrating with standard protocols such as <a href="https://openid.net/">openid</a>, <a href="https://oauth.net/2/">oauth2</a> and <a href="https://en.wikipedia.org/wiki/Security_Assertion_Markup_Language">SAML</a>.</li>
<li>Evaluate the authentication flows I need and avoid increasing scope and risk.</li>
<li>Try to use a service to start with, or secondarily, an opensource project with a good security process and a healthy community.</li>
<li>Limit any custom development to extensions, rather than throwing out the baby with the bath water.</li>
</ol>
<p>As you can probably tell, my primary goal is to keep authentication out of my applications, I really don&rsquo;t have the time or inclination to manage a handcrafted authentication solution.</p>
<h3 id="what-does-aws-cognito-provide-out-of-the-box">What does AWS Cognito provide out of the box?</h3>
<p>Lets look at what we get out of the box:</p>
<ul>
<li>Storing and protecting your users data with features such as <a href="https://en.wikipedia.org/wiki/Secure_Remote_Password_protocol">Secure Remote Password Protocol (SRP)</a>.</li>
<li>Signing up for an account with email / sms verification</li>
<li>Signing in, optionally with Multi Factor Authentication (MFA)</li>
<li>Password change and recovery</li>
<li>A number of triggers which can be used to extend the product</li>
</ul>
<h3 id="what-is-great-about-cognito">What is great about Cognito?</h3>
<p>Where AWS Cognito really shines is:</p>
<ul>
<li>Out of the box <a href="https://aws.amazon.com/compliance/services-in-scope/">compliance to standards such as SOC and PCI</a></li>
<li>Integration with a range of <a href="https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-social-idp.html">platform identity providers</a>, such as Google, Apple and Amazon</li>
<li>Support for integration with identity providers (IdPs) using OpenID and SAML.</li>
<li>Really easy to integrate into your application using libraries such as <a href="https://github.com/aws-amplify/amplify-js">AmplifyJS</a>.</li>
<li>AWS is managing it for a minimal cost</li>
</ul>
<h3 id="what-is-not-so-great-about-cognito">What is not so great about Cognito?</h3>
<p>Where AWS Cognito can be a challenge for developers:</p>
<ul>
<li>Can be difficult to setup, and understand some of the settings which can only be updated during creation, changing these requires you to delete and recreate your pool.</li>
<li>Per account quotas on API calls</li>
<li>A lack of search</li>
<li>No inbuilt to backup and restore the user data in your pool</li>
</ul>
<p>So how do we address some of these challenges, while still getting the value provided and being able to capitalise on it&rsquo;s security and compliance features.</p>
<h3 id="what-is-the-best-way-to-setup-cognito">What is the best way to setup Cognito?</h3>
<p>To setup Cognito I typically use one of the many open source <a href="https://aws.amazon.com/cloudformation/">cloudformation</a> templates on <a href="https://github.com/">GitHub</a>. I crafted this template some time ago <a href="https://gist.github.com/wolfeidau/70531fc1a593c0bad7fb9ebc9ae82580">cognito.yml</a>, it supports login using <code>email</code> address, and domain white listing for sign ups.</p>
<p>As a follow on from this I built a serverless application <a href="https://github.com/wolfeidau/serverless-cognito-auth">serverless-cognito-auth</a> which encapsulates a lot of the standard functionality I use in applications.</p>
<p>You can also use <a href="https://docs.aws.amazon.com/aws-mobile/latest/developerguide/mobile-hub-features.html">AWS Mobile Hub</a> or <a href="https://aws.amazon.com/amplify/">AWS Amplify</a> to bootstrap a Cognito pool for you.</p>
<p>Overall recommendations are:</p>
<ol>
<li>If your new to Cognito and want things to just work then I recommend trying <a href="https://aws.amazon.com/amplify/">AWS Amplify</a>.</li>
<li>If you are an old hand and just want Cognito the way you like it, then use one of the many prebuilt templates.</li>
</ol>
<h3 id="how-do-i-avoid-quota-related-issues">How do I avoid quota related issues?</h3>
<p>Firstly I recommend familiarising yourself with the <a href="https://docs.aws.amazon.com/cognito/latest/developerguide/limits.html">AWS Cognito Limits Page</a>.</p>
<p>I haven&rsquo;t seen an application hit request rate this more than a couple of times, and both those were related to UI bugs which continuously polled the Cognito API.</p>
<p>The one limit I have seen hit is the sign up emails per day limit, this can be a pain on launch days for apps, or when there is a spike in sign ups. If your planning to use Cognito in a startup you will need to integrate with <a href="https://aws.amazon.com/ses/">SES</a>.</p>
<h3 id="how-do-i-work-around-searching-my-user-database">How do I work around searching my user database?</h3>
<p>Out of the box cognito will only allow you to list and filter users by a list of common attributes, this doesn&rsquo;t include custom attributes, so if you add an attribute like customerId you won&rsquo;t be able to find all users with a given value.</p>
<p>This limitation makes it difficult to replace an internal database driven authentication library just using the cognito service, so for this reason I recommend adding a DynamoDB table to your application and integrating this with cognito using <a href="https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html">lambda triggers</a> to build your own global user store.</p>
<p>To simplify interacting with Cognito I wrote a CLI which provides some helpful commands to scan, filter, export and perform some common admin functions, you can find it at <a href="https://github.com/wolfeidau/cognito-cli">https://github.com/wolfeidau/cognito-cli</a>.</p>
<h3 id="how-do-i-back-up-my-user-pool">How do I back up my user pool?</h3>
<p>Backing up user accounts in any system is something you need to consider carefully as this information typically includes credentials as well as other sensitive data such as mobile number which is often used as a second factor for other services.</p>
<p>Currently Cognito doesn&rsquo;t provide a simple way of exporting user data, the service does however have an import function which will import users in from a CSV file.</p>
<p><strong>Note:</strong> AWS cognito doesn&rsquo;t support export user passwords, these will need to be reset after restore.</p>
<p>For some examples of tooling see <a href="https://www.npmjs.com/package/cognito-backup-restore">cognito-backup-restore</a>.</p>
<h1 id="conclusion">Conclusion</h1>
<p>If you really care about security and compliance then cognito is a great solution, it has some limitations, and gaps but these can be worked around if you want to focus your effort somewhere else.</p>
<p>Personally I think it is really important that as a developer I pick solutions which ensure my customers data is locked away as securely as possible, and ideally using a managed service.</p>
<p>You could totally roll your own authentication solution, and manage all the patching and challenges which go with that but that makes very little sense when you should probably be solving the original problem you had.</p>
<p>Authentication is a <a href="https://americanexpress.io/yak-shaving/">yak I am willing to let someone else <del>shave</del></a>  manage, and so should you, if not for your own sanity, then that of your users.</p>
<p>Lastly if your building out a web application use <a href="https://aws-amplify.github.io/amplify-js/api/">amplify-js</a>, this library makes it so easy to add Cognito authentication to your web application. I used it on <a href="https://github.com/wolfeidau/cognito-vue-bootstrap">cognito-vue-bootstrap</a> which you can also check out.</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
