<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/rss-style.xsl" type="text/xsl"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	     xmlns:dc="http://purl.org/dc/elements/1.1/"
	   xmlns:atom="http://www.w3.org/2005/Atom"
	     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	  xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>IETF &#8211; Terence Eden’s Blog</title>
	<atom:link href="https://shkspr.mobi/blog/tag/ietf/feed/" rel="self" type="application/rss+xml" />
	<link>https://shkspr.mobi/blog</link>
	<description>Regular nonsense about tech and its effects 🙃</description>
	<lastBuildDate>Sat, 25 Oct 2025 20:13:42 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://shkspr.mobi/blog/wp-content/uploads/2023/07/cropped-avatar-32x32.jpeg</url>
	<title>IETF &#8211; Terence Eden’s Blog</title>
	<link>https://shkspr.mobi/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title><![CDATA[Alpha launch - .well-known/avatar - feedback wanted]]></title>
		<link>https://shkspr.mobi/blog/2025/10/alpha-launch-well-known-avatar-feedback-wanted/</link>
					<comments>https://shkspr.mobi/blog/2025/10/alpha-launch-well-known-avatar-feedback-wanted/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sat, 25 Oct 2025 11:34:10 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[IETF]]></category>
		<category><![CDATA[ReDeCentralize]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[web]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=64078</guid>

					<description><![CDATA[I&#039;ve gotten sufficiently annoyed with a trivial problem that I&#039;m preparing to write an IETF RFC. Yeah. That&#039;s how ticked off I am!  Every site that I sign up for asks me to upload an avatar to represent myself. Whenever I change my photo, I have to log in to a hundred sites and change it there.  Perhaps they could all use Gravatar - but that&#039;s a centralised service and doesn&#039;t work with wildcard…]]></description>
										<content:encoded><![CDATA[<p>I've gotten sufficiently annoyed with a trivial problem that I'm preparing to write an IETF RFC. Yeah. That's how ticked off I am!</p>

<p>Every site that I sign up for asks me to upload an avatar to represent myself. Whenever I change my photo, I have to log in to a hundred sites and change it there<sup id="fnref:ok"><a href="https://shkspr.mobi/blog/2025/10/alpha-launch-well-known-avatar-feedback-wanted/#fn:ok" class="footnote-ref" title="OK, I don't have to. But I want to. I dislike having last year's photo cluttering some half-remembered social network." role="doc-noteref">0</a></sup>.</p>

<p>Perhaps they could all use <a href="https://gravatar.com/">Gravatar</a> - but that's a centralised service<sup id="fnref:boo"><a href="https://shkspr.mobi/blog/2025/10/alpha-launch-well-known-avatar-feedback-wanted/#fn:boo" class="footnote-ref" title="We live in the redecentralised future now!" role="doc-noteref">1</a></sup> and doesn't work with wildcard email addresses. <a href="https://libravatar.org/">Libravatar</a> also relies on email addresses and requires implementers to set up new DNS entries.</p>

<p>So I'm proposing <code>.well-known/avatar</code>. Here's how it works (for now). I'd like your feedback before going further<sup id="fnref:slow"><a href="https://shkspr.mobi/blog/2025/10/alpha-launch-well-known-avatar-feedback-wanted/#fn:slow" class="footnote-ref" title="I wrote about this in 2004 and in 2020. It takes me time, but I get there eventually!" role="doc-noteref">2</a></sup>.</p>

<p>I sign up to a service and use the email address <code>whatever@shkspr.mobi</code>.</p>

<p>The service looks up my avatar using a well-known path. For example, request <a href="https://shkspr.mobi/.well-known/avatar?resource=acct:whatever@shkspr.mobi">https://shkspr.mobi/.well-known/avatar?resource=acct:whatever@shkspr.mobi</a> and you'll get back this JSON:</p>

<pre><code class="language-json">{
    "subject": "acct:whatever@shkspr.mobi",
    "links": [
        {
              "rel": "http:\/\/webfinger.net\/rel\/avatar",
             "type": "image\/webp",
             "href": "https:\/\/shkspr.mobi\/.well-known\/avatar\/avatar-1024.webp",
            "sizes": "1024x1024"
        },
        {
              "rel": "http:\/\/webfinger.net\/rel\/avatar",
             "type": "image\/jpeg",
             "href": "https:\/\/shkspr.mobi\/.well-known\/avatar\/avatar-512.jpg",
            "sizes": "512x512"
        }
    ]
}
</code></pre>

<p>That's a slightly enhanced <a href="https://webfinger.net/rel/#avatar">https://webfinger.net/rel/#avatar</a> which adds <a href="https://html.spec.whatwg.org/multipage/semantics.html#attr-link-sizes">a <code>sizes</code> parameter</a>.  The service can then pick the appropriate MIME and size.</p>

<p>Alternatively, you can request the same URl but with a header of <code>Accept: image/gif</code> and receive the default sized avatar in that specific format.</p>

<p>Try it by running:</p>

<pre><code class="language-bash">curl -H "Accept: image/avif" https://shkspr.mobi/.well-known/avatar/ --output "test.avif"
</code></pre>

<p>You should receive an auto-converted version of my avatar.</p>

<h2 id="some-thoughts"><a href="https://shkspr.mobi/blog/2025/10/alpha-launch-well-known-avatar-feedback-wanted/#some-thoughts">Some Thoughts</a></h2>

<p>Please add your thoughts to the comments box. Here's some feedback I've received so far.</p>

<p>Perhaps this is too complicated? What's wrong with just serving up an image when the URl is requested? That would make it easier for static sites.</p>

<div class="activitypub-embed u-in-reply-to h-cite"> <div class="activitypub-embed-header p-author h-card"> <img class="u-photo" src="https://cdn.fosstodon.org/accounts/avatars/000/061/904/original/5e6ac0188b3ab021.png" alt=""> <div class="activitypub-embed-header-text"> <h2 class="p-name" id="simon-josefsson"><a href="https://shkspr.mobi/blog/2025/10/alpha-launch-well-known-avatar-feedback-wanted/#simon-josefsson">Simon Josefsson</a></h2> <a href="https://fosstodon.org/users/jas" class="ap-account u-url">@jas@fosstodon.org</a> </div> </div> <div class="activitypub-embed-content"> <div class="ap-subtitle p-summary e-content"><p><span class="h-card"><a href="https://mastodon.social/@Edent" class="u-url mention">@<span>Edent</span></a></span> Thinking about this, while I like content negotiation as a clever hack, I wonder if maybe it isn’t too clever. The nice thing with WKD is that you can deploy it with any normal static HTTP file without any special magic. Maybe the protocol could be dumbed down to simply rely on WKD-style URLs? I’m not sure how to configure my web server (Apache) for your avatar well known URL with negotiation magic.</p></div> </div> <div class="activitypub-embed-meta"> <a href="https://fosstodon.org/users/jas/statuses/115424507307729006" class="ap-stat ap-date dt-published u-in-reply-to">2025-10-23, 16:50</a> <span class="ap-stat"> <strong>0</strong> boosts </span> <span class="ap-stat"> <strong>1</strong> favorites </span> </div> </div>

<style>/** * ActivityPub embed styles. */ .activitypub-embed { background: #fff; border: 1px solid #e6e6e6; border-radius: 12px; padding: 0; max-width: 100%; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; } .activitypub-reply-block .activitypub-embed { margin: 1em 0; } .activitypub-embed-header { padding: 15px; display: flex; align-items: center; gap: 10px; } .activitypub-embed-header img { width: 48px; height: 48px; border-radius: 50%; } .activitypub-embed-header-text { flex-grow: 1; } .activitypub-embed-header-text h2 { color: #000; font-size: 15px; font-weight: 600; margin: 0; padding: 0; } .activitypub-embed-header-text .ap-account { color: #687684; font-size: 14px; text-decoration: none; } .activitypub-embed-content { padding: 0 15px 15px; } .activitypub-embed-content .ap-title { font-size: 23px; font-weight: 600; margin: 0 0 10px; padding: 0; color: #000; } .activitypub-embed-content .ap-subtitle { font-size: 15px; color: #000; margin: 0 0 15px; } .activitypub-embed-content .ap-preview { border: 1px solid #e6e6e6; border-radius: 8px; overflow: hidden; } .activitypub-embed-content .ap-preview img { width: 100%; height: auto; display: block; } .activitypub-embed-content .ap-preview { border-radius: 8px; box-sizing: border-box; display: grid; gap: 2px; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; margin: 1em 0 0; min-height: 64px; overflow: hidden; position: relative; width: 100%; } .activitypub-embed-content .ap-preview.layout-1 { grid-template-columns: 1fr; grid-template-rows: 1fr; } .activitypub-embed-content .ap-preview.layout-2 { aspect-ratio: auto; grid-template-rows: 1fr; height: auto; } .activitypub-embed-content .ap-preview.layout-3 > img:first-child { grid-row: span 2; } .activitypub-embed-content .ap-preview img { border: 0; box-sizing: border-box; display: inline-block; height: 100%; object-fit: cover; overflow: hidden; position: relative; width: 100%; } .activitypub-embed-content .ap-preview video, .activitypub-embed-content .ap-preview audio { max-width: 100%; display: block; grid-column: 1 / span 2; } .activitypub-embed-content .ap-preview audio { width: 100%; } .activitypub-embed-content .ap-preview-text { padding: 15px; } .activitypub-embed-meta { padding: 15px; border-top: 1px solid #e6e6e6; color: #687684; font-size: 13px; display: flex; gap: 15px; } .activitypub-embed-meta .ap-stat { display: flex; align-items: center; gap: 5px; } @media only screen and (max-width: 399px) { .activitypub-embed-meta span.ap-stat { display: none !important; } } .activitypub-embed-meta a.ap-stat { color: inherit; text-decoration: none; } .activitypub-embed-meta strong { font-weight: 600; color: #000; } .activitypub-embed-meta .ap-stat-label { color: #687684; } </style>

<p>What about a size parameter?</p>

<div class="activitypub-embed u-in-reply-to h-cite"> <div class="activitypub-embed-header p-author h-card"> <img class="u-photo" src="https://mastocdn.talking.dev/accounts/avatars/106/551/937/719/290/584/original/733b34a017037146.jpg" alt=""> <div class="activitypub-embed-header-text"> <h2 class="p-name" id="chip"><a href="https://shkspr.mobi/blog/2025/10/alpha-launch-well-known-avatar-feedback-wanted/#chip">Chip</a></h2> <a href="https://talking.dev/users/chip" class="ap-account u-url">@chip@talking.dev</a> </div> </div> <div class="activitypub-embed-content"> <div class="ap-subtitle p-summary e-content"><p><span class="h-card"><a href="https://mastodon.social/@Edent" class="u-url mention">@<span>Edent</span></a></span> It'd be nice if the query could limit the size of the avatar being returned. If only there were `Accept-Max-Size`, but maybe a query param? I wouldn't want my performance taking a dive if Alice has a 35M avatar that my client starts downloading. If my client had requested with `max_size=3072` I'd rather not see the avatar than degrade performance/pull excess data</p></div> </div> <div class="activitypub-embed-meta"> <a href="https://talking.dev/users/chip/statuses/115424082361331622" class="ap-stat ap-date dt-published u-in-reply-to">2025-10-23, 15:02</a> <span class="ap-stat"> <strong>0</strong> boosts </span> <span class="ap-stat"> <strong>1</strong> favorites </span> </div> </div>

<style>/** * ActivityPub embed styles. */ .activitypub-embed { background: #fff; border: 1px solid #e6e6e6; border-radius: 12px; padding: 0; max-width: 100%; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; } .activitypub-reply-block .activitypub-embed { margin: 1em 0; } .activitypub-embed-header { padding: 15px; display: flex; align-items: center; gap: 10px; } .activitypub-embed-header img { width: 48px; height: 48px; border-radius: 50%; } .activitypub-embed-header-text { flex-grow: 1; } .activitypub-embed-header-text h2 { color: #000; font-size: 15px; font-weight: 600; margin: 0; padding: 0; } .activitypub-embed-header-text .ap-account { color: #687684; font-size: 14px; text-decoration: none; } .activitypub-embed-content { padding: 0 15px 15px; } .activitypub-embed-content .ap-title { font-size: 23px; font-weight: 600; margin: 0 0 10px; padding: 0; color: #000; } .activitypub-embed-content .ap-subtitle { font-size: 15px; color: #000; margin: 0 0 15px; } .activitypub-embed-content .ap-preview { border: 1px solid #e6e6e6; border-radius: 8px; overflow: hidden; } .activitypub-embed-content .ap-preview img { width: 100%; height: auto; display: block; } .activitypub-embed-content .ap-preview { border-radius: 8px; box-sizing: border-box; display: grid; gap: 2px; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; margin: 1em 0 0; min-height: 64px; overflow: hidden; position: relative; width: 100%; } .activitypub-embed-content .ap-preview.layout-1 { grid-template-columns: 1fr; grid-template-rows: 1fr; } .activitypub-embed-content .ap-preview.layout-2 { aspect-ratio: auto; grid-template-rows: 1fr; height: auto; } .activitypub-embed-content .ap-preview.layout-3 > img:first-child { grid-row: span 2; } .activitypub-embed-content .ap-preview img { border: 0; box-sizing: border-box; display: inline-block; height: 100%; object-fit: cover; overflow: hidden; position: relative; width: 100%; } .activitypub-embed-content .ap-preview video, .activitypub-embed-content .ap-preview audio { max-width: 100%; display: block; grid-column: 1 / span 2; } .activitypub-embed-content .ap-preview audio { width: 100%; } .activitypub-embed-content .ap-preview-text { padding: 15px; } .activitypub-embed-meta { padding: 15px; border-top: 1px solid #e6e6e6; color: #687684; font-size: 13px; display: flex; gap: 15px; } .activitypub-embed-meta .ap-stat { display: flex; align-items: center; gap: 5px; } @media only screen and (max-width: 399px) { .activitypub-embed-meta span.ap-stat { display: none !important; } } .activitypub-embed-meta a.ap-stat { color: inherit; text-decoration: none; } .activitypub-embed-meta strong { font-weight: 600; color: #000; } .activitypub-embed-meta .ap-stat-label { color: #687684; } </style>

<p>Will anyone actually use it?</p>

<div class="activitypub-embed u-in-reply-to h-cite"> <div class="activitypub-embed-header p-author h-card"> <img class="u-photo" src="https://fedi.splitbrain.org/fileserver/013DGS4XRNRZTWPDP5Q2MKSHZR/attachment/original/01JNBFPHNR06RXDG36V0VM7D3V.jpeg" alt=""> <div class="activitypub-embed-header-text"> <h2 class="p-name" id="andreas-gohr"><a href="https://shkspr.mobi/blog/2025/10/alpha-launch-well-known-avatar-feedback-wanted/#andreas-gohr">Andreas Gohr</a></h2> <a href="https://fedi.splitbrain.org/users/splitbrain" class="ap-account u-url">@splitbrain@fedi.splitbrain.org</a> </div> </div> <div class="activitypub-embed-content"> <div class="ap-subtitle p-summary e-content"><p><span class="h-card"><a href="https://mastodon.social/@Edent" class="u-url mention" rel="nofollow noreferrer noopener" target="_blank">@<span>Edent</span></a></span> good luck with getting the hundreds of services to implement it. I mean it. it would be awesome and you might be well connected enough to make it happen.</p></div> </div> <div class="activitypub-embed-meta"> <a href="https://fedi.splitbrain.org/users/splitbrain/statuses/01K88SH504PEK5X8C6MSXRY0YH" class="ap-stat ap-date dt-published u-in-reply-to">2025-10-23, 15:03</a> </div> </div>

<style>/** * ActivityPub embed styles. */ .activitypub-embed { background: #fff; border: 1px solid #e6e6e6; border-radius: 12px; padding: 0; max-width: 100%; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; } .activitypub-reply-block .activitypub-embed { margin: 1em 0; } .activitypub-embed-header { padding: 15px; display: flex; align-items: center; gap: 10px; } .activitypub-embed-header img { width: 48px; height: 48px; border-radius: 50%; } .activitypub-embed-header-text { flex-grow: 1; } .activitypub-embed-header-text h2 { color: #000; font-size: 15px; font-weight: 600; margin: 0; padding: 0; } .activitypub-embed-header-text .ap-account { color: #687684; font-size: 14px; text-decoration: none; } .activitypub-embed-content { padding: 0 15px 15px; } .activitypub-embed-content .ap-title { font-size: 23px; font-weight: 600; margin: 0 0 10px; padding: 0; color: #000; } .activitypub-embed-content .ap-subtitle { font-size: 15px; color: #000; margin: 0 0 15px; } .activitypub-embed-content .ap-preview { border: 1px solid #e6e6e6; border-radius: 8px; overflow: hidden; } .activitypub-embed-content .ap-preview img { width: 100%; height: auto; display: block; } .activitypub-embed-content .ap-preview { border-radius: 8px; box-sizing: border-box; display: grid; gap: 2px; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; margin: 1em 0 0; min-height: 64px; overflow: hidden; position: relative; width: 100%; } .activitypub-embed-content .ap-preview.layout-1 { grid-template-columns: 1fr; grid-template-rows: 1fr; } .activitypub-embed-content .ap-preview.layout-2 { aspect-ratio: auto; grid-template-rows: 1fr; height: auto; } .activitypub-embed-content .ap-preview.layout-3 > img:first-child { grid-row: span 2; } .activitypub-embed-content .ap-preview img { border: 0; box-sizing: border-box; display: inline-block; height: 100%; object-fit: cover; overflow: hidden; position: relative; width: 100%; } .activitypub-embed-content .ap-preview video, .activitypub-embed-content .ap-preview audio { max-width: 100%; display: block; grid-column: 1 / span 2; } .activitypub-embed-content .ap-preview audio { width: 100%; } .activitypub-embed-content .ap-preview-text { padding: 15px; } .activitypub-embed-meta { padding: 15px; border-top: 1px solid #e6e6e6; color: #687684; font-size: 13px; display: flex; gap: 15px; } .activitypub-embed-meta .ap-stat { display: flex; align-items: center; gap: 5px; } @media only screen and (max-width: 399px) { .activitypub-embed-meta span.ap-stat { display: none !important; } } .activitypub-embed-meta a.ap-stat { color: inherit; text-decoration: none; } .activitypub-embed-meta strong { font-weight: 600; color: #000; } .activitypub-embed-meta .ap-stat-label { color: #687684; } </style>

<p>What about hashing the email?</p>

<div class="activitypub-embed u-in-reply-to h-cite"> <div class="activitypub-embed-header p-author h-card"> <img class="u-photo" src="https://media.social.lol/accounts/avatars/111/559/923/870/165/558/original/5c1a92fdf91205a8.png" alt=""> <div class="activitypub-embed-header-text"> <h2 class="p-name" id="david-bushell-%f0%9f%8e%ae"><a href="https://shkspr.mobi/blog/2025/10/alpha-launch-well-known-avatar-feedback-wanted/#david-bushell-%f0%9f%8e%ae">David Bushell 🎮</a></h2> <a href="https://social.lol/users/db" class="ap-account u-url">@db@social.lol</a> </div> </div> <div class="activitypub-embed-content"> <div class="ap-subtitle p-summary e-content"><p><span class="h-card"><a href="https://mastodon.social/@Edent" class="u-url mention">@<span>Edent</span></a></span> would using a hash of the email address in its place improve privacy? 🤔</p></div> </div> <div class="activitypub-embed-meta"> <a href="https://social.lol/users/db/statuses/115434663342778931" class="ap-stat ap-date dt-published u-in-reply-to">2025-10-25, 11:52</a> <span class="ap-stat"> <strong>0</strong> boosts </span> <span class="ap-stat"> <strong>0</strong> favorites </span> </div> </div>

<style>/** * ActivityPub embed styles. */ .activitypub-embed { background: #fff; border: 1px solid #e6e6e6; border-radius: 12px; padding: 0; max-width: 100%; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; } .activitypub-reply-block .activitypub-embed { margin: 1em 0; } .activitypub-embed-header { padding: 15px; display: flex; align-items: center; gap: 10px; } .activitypub-embed-header img { width: 48px; height: 48px; border-radius: 50%; } .activitypub-embed-header-text { flex-grow: 1; } .activitypub-embed-header-text h2 { color: #000; font-size: 15px; font-weight: 600; margin: 0; padding: 0; } .activitypub-embed-header-text .ap-account { color: #687684; font-size: 14px; text-decoration: none; } .activitypub-embed-content { padding: 0 15px 15px; } .activitypub-embed-content .ap-title { font-size: 23px; font-weight: 600; margin: 0 0 10px; padding: 0; color: #000; } .activitypub-embed-content .ap-subtitle { font-size: 15px; color: #000; margin: 0 0 15px; } .activitypub-embed-content .ap-preview { border: 1px solid #e6e6e6; border-radius: 8px; overflow: hidden; } .activitypub-embed-content .ap-preview img { width: 100%; height: auto; display: block; } .activitypub-embed-content .ap-preview { border-radius: 8px; box-sizing: border-box; display: grid; gap: 2px; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; margin: 1em 0 0; min-height: 64px; overflow: hidden; position: relative; width: 100%; } .activitypub-embed-content .ap-preview.layout-1 { grid-template-columns: 1fr; grid-template-rows: 1fr; } .activitypub-embed-content .ap-preview.layout-2 { aspect-ratio: auto; grid-template-rows: 1fr; height: auto; } .activitypub-embed-content .ap-preview.layout-3 > img:first-child { grid-row: span 2; } .activitypub-embed-content .ap-preview img { border: 0; box-sizing: border-box; display: inline-block; height: 100%; object-fit: cover; overflow: hidden; position: relative; width: 100%; } .activitypub-embed-content .ap-preview video, .activitypub-embed-content .ap-preview audio { max-width: 100%; display: block; grid-column: 1 / span 2; } .activitypub-embed-content .ap-preview audio { width: 100%; } .activitypub-embed-content .ap-preview-text { padding: 15px; } .activitypub-embed-meta { padding: 15px; border-top: 1px solid #e6e6e6; color: #687684; font-size: 13px; display: flex; gap: 15px; } .activitypub-embed-meta .ap-stat { display: flex; align-items: center; gap: 5px; } @media only screen and (max-width: 399px) { .activitypub-embed-meta span.ap-stat { display: none !important; } } .activitypub-embed-meta a.ap-stat { color: inherit; text-decoration: none; } .activitypub-embed-meta strong { font-weight: 600; color: #000; } .activitypub-embed-meta .ap-stat-label { color: #687684; } </style>

<p>You've already given the service your email address, and your domain already knows your account name - so there's no privacy leak here. Obviously, a service shouldn't hotlink to your avatar image.</p>

<p>How about DNS?</p>

<blockquote class="bluesky-embed" data-bluesky-uri="at://did:plc:en7czkhogfoggztn3newgk3u/app.bsky.feed.post/3m3zdjv7vcs2v" data-bluesky-cid="bafyreibp7hypzhpjiwairnihopr47fdifwasluludaxobybpnna3jcupzu"><p lang="en">I like it. Is there an argument that service / endpoint should be specifiable at the DNS level?As others in your comments pointed out, if your site is currently just static, some users might prefer to run an entirely separate dedicated avatar service.</p>— <a href="https://bsky.app/profile/did:plc:en7czkhogfoggztn3newgk3u?ref_src=embed">Emily Shepherd (@emi.ly)</a> <a href="https://bsky.app/profile/did:plc:en7czkhogfoggztn3newgk3u/post/3m3zdjv7vcs2v?ref_src=embed">2025-10-25T11:57:43.456Z</a></blockquote>

<script async="" src="https://embed.bsky.app/static/embed.js" charset="utf-8"></script>

<p>Personally, I think that's a bit complicated, but I'm happy to be convinced.</p>

<blockquote><p><a href="https://bsky.app/profile/ox.ca/post/3m3zkrun4j22b">Is this restricted to email?</a></p></blockquote>

<p>No! For example, if you know my GitHub username then you should be able to get the avatar from <code>https://github.com/.well-known/avatar?resource=acct:edent</code></p>

<blockquote><p><a href="https://mechadarwin.com/2025/10/25/well-known-avatar-location/">How can a service tell if the avatar has been updated</a>?</p></blockquote>

<p>Perhaps a hash, timestamp, or something else?</p>

<blockquote><p><a href="https://mastodon.bsd.cafe/@gumnos/115436604786371047">Can requests for multiple accounts be sent at once?</a></p></blockquote>

<p>I'm not sure how / if WebFinger handles this. I suppose there ought to be some limit to avoid overwhelming a server.</p>

<h2 id="proposal"><a href="https://shkspr.mobi/blog/2025/10/alpha-launch-well-known-avatar-feedback-wanted/#proposal">Proposal</a></h2>

<p>I think the default should be to return an image.</p>

<p>If an accept of <code>image/…</code> is requested, the server should try to return an image in that format.</p>

<p>If an accept of <code>application/json</code> or similar is requested, the server should return a JSON document listing the available avatars.</p>

<p>I don't think a <code>?size=</code> GET parameter is necessary; services can resize once they've downloaded, or use the JSON document to get the right size.</p>

<p>A limited amount of alt text could be added using <a href="https://www.rfc-editor.org/rfc/rfc7033#section-4.4.4.4">the title attribute</a> in the JSON.</p>

<p>Before I start writing up anything formal - I'd love your constructive criticism on this.</p>

<div id="footnotes" role="doc-endnotes">
<hr aria-label="Footnotes">
<ol start="0">

<li id="fn:ok">
<p>OK, I don't <em>have</em> to. But I <em>want</em> to. I dislike having last year's photo cluttering some half-remembered social network.&nbsp;<a href="https://shkspr.mobi/blog/2025/10/alpha-launch-well-known-avatar-feedback-wanted/#fnref:ok" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>

<li id="fn:boo">
<p>We live in the redecentralised future now!&nbsp;<a href="https://shkspr.mobi/blog/2025/10/alpha-launch-well-known-avatar-feedback-wanted/#fnref:boo" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>

<li id="fn:slow">
<p>I wrote about this in <a href="https://shkspr.mobi/blog/2024/03/well-known-avatar/">2004</a> and in <a href="https://shkspr.mobi/blog/2020/03/one-avatar-to-rule-them-all/">2020</a>. It takes me time, but I get there eventually!&nbsp;<a href="https://shkspr.mobi/blog/2025/10/alpha-launch-well-known-avatar-feedback-wanted/#fnref:slow" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>

</ol>
</div>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=64078&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2025/10/alpha-launch-well-known-avatar-feedback-wanted/feed/</wfw:commentRss>
			<slash:comments>16</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[.well-known/avatar]]></title>
		<link>https://shkspr.mobi/blog/2024/03/well-known-avatar/</link>
					<comments>https://shkspr.mobi/blog/2024/03/well-known-avatar/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sun, 17 Mar 2024 12:34:47 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[avatar]]></category>
		<category><![CDATA[IETF]]></category>
		<category><![CDATA[open standards]]></category>
		<category><![CDATA[standards]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=49907</guid>

					<description><![CDATA[Hot on the heels of a post I wrote 4 years ago, wouldn&#039;t it be useful to have a well-known URl for user avatar images?  When I sign up to a web service, I don&#039;t want to faff around uploading an image to use as my avatar. I want that service to look at my email address or social-sign-in and automatically pick up my preferred graphic.  Here&#039;s how I see it working.   A user signs in to a service…]]></description>
										<content:encoded><![CDATA[<p>Hot on the heels of <a href="https://shkspr.mobi/blog/2020/03/one-avatar-to-rule-them-all/">a post I wrote 4 years ago</a>, wouldn't it be useful to have a <a href="https://en.wikipedia.org/wiki/Well-known_URI">well-known URl</a> for user avatar images?</p>

<p>When I sign up to a web service, I don't want to faff around uploading an image to use as my avatar. I want that service to look at my email address or social-sign-in and automatically pick up my preferred graphic.</p>

<p>Here's how I see it working.</p>

<ol>
<li>A user signs in to a service with the email address <code>username@example.com</code></li>
<li>In a similar way to <a href="https://www.rfc-editor.org/rfc/rfc7033">WebFinger</a>, the service makes a request to:

<ul>
<li><code>example.com/.well-known/avatar?resource=acct:username@example.com</code></li>
</ul></li>
<li>If the request's <code>Accept</code> header has a MIME type of <code>image/*</code>, then the server immediately returns an image.</li>
<li>If the request's <code>Accept</code> header has a MIME type of <code>application/json</code>, then the server can return a WebFinger-style document with <code>"rel":"http://webfinger.net/rel/avatar"</code> and, perhaps, a list of different images, formats, and sizes.</li>
</ol>

<p>This makes it incredibly simple for people to use the same avatar <em>everywhere</em>.</p>

<p>It also means that if you're designing a service which publicly shows usernames, you can make avatars available without an expensive API call. For example, Twitter could make user's avatars available at:
<code>twitter.com/.well-known/avatars?resource=acct:edent</code></p>

<h2 id="but-what-about"><a href="https://shkspr.mobi/blog/2024/03/well-known-avatar/#but-what-about">But what about...?</a></h2>

<p>This is a sketch of an idea. I'd like to know if people think it is useful before I take it any further.</p>

<p>I don't think it breaches privacy - a user's image is public on all services anyway.</p>

<p>Users should still be given the option of changing their avatar if they want.</p>

<p>A service shouldn't expose the user's email address - they should proxy the image.</p>

<p>Anything else I should have thought of?</p>

<p><ins datetime="2024-03-18T15:05:30+00:00">Updates</ins></p>

<p>To stave off some common points raised.</p>

<ul>
<li>No this isn't like <a href="https://shkspr.mobi/blog/2020/03/one-avatar-to-rule-them-all/">Gravatar</a>. That works by being a 3rd party service and using the MD5 of your email address.</li>
<li>No this isn't like <a href="https://www.libravatar.org/">Libravatar</a>. See above.</li>
<li>No this isn't like WebFinger. That only returns JSON.</li>
<li>No this isn't like h-card. That requires a server to parse HTML in order to find an image.</li>
<li>No this isn't like <a href="https://shkspr.mobi/blog/2022/08/dns-esoterica-bimi-svg-in-dns-txt-wtf/">BIMI</a>. That's expensive and only supports SVG.</li>
</ul>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=49907&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/03/well-known-avatar/feed/</wfw:commentRss>
			<slash:comments>31</slash:comments>
		
		
			</item>
	</channel>
</rss>
