{"id":672,"date":"2023-10-03T23:20:37","date_gmt":"2023-10-03T21:20:37","guid":{"rendered":"https:\/\/www.dont-panic.cc\/capi\/?p=672"},"modified":"2023-10-03T23:20:38","modified_gmt":"2023-10-03T21:20:38","slug":"bluesky-with-own-domain-handle-and-well-known-atproto-did","status":"publish","type":"post","link":"https:\/\/www.dont-panic.cc\/capi\/2023\/10\/03\/bluesky-with-own-domain-handle-and-well-known-atproto-did\/","title":{"rendered":"Bluesky with own domain-handle and .well-known\/atproto-did"},"content":{"rendered":"\n<p><strong>TLDR:<\/strong> Beware that there must be no newline at the end of the .well-known\/atproto-did file and that the content type needs to be <code>text\/plain<\/code>. <code>echo -n<\/code> to the rescue instead of <code>vim<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>I recently received an invite to <a href=\"https:\/\/bsky.app\/\">Bluesky<\/a> and so far I&#8217;ve enjoyed the experience. Early-day Twitter feeling. Can recommend to check it out if you get an invite.<\/p>\n\n\n\n<p>One very intriguing thing is that Bluesky allows for your own domain to be your handle. So I decided to go with <a href=\"https:\/\/bsky.app\/profile\/martin.dont-panic.cc\">@martin.dont-panic.cc<\/a>. <\/p>\n\n\n\n<p>The process is described in <a href=\"https:\/\/blueskyweb.xyz\/blog\/4-28-2023-domain-handle-tutorial\" data-type=\"link\" data-id=\"https:\/\/blueskyweb.xyz\/blog\/4-28-2023-domain-handle-tutorial\">a blog post by Bluesky<\/a>. There are two main options to verify your domain ownership, DNS TXT entries or an HTTPS request to <code>https:\/\/martin.dont-panic.cc\/.well-known\/atproto-did<\/code> (in my case). Since everyone is doing DNS, I wanted to try out HTTPS\/.well-known. (Of course, there needs to be a martin.dont-panic.cc DNS entry to get to the web-server, but no special TXT header for the verification.)<\/p>\n\n\n\n<p>I wanted to serve the file as a static file in the filesystem via <a href=\"https:\/\/www.nginx.com\/\" data-type=\"link\" data-id=\"https:\/\/www.nginx.com\/\">nginx<\/a>. So I set up the following static nginx configuration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server {\n        listen 443 ssl;\n        server_name martin.dont-panic.cc;\n\n        root \/var\/www\/cc\/dont-panic\/martin\/;\n        index index.html;\n        location \/ {\n                # First attempt to serve request as file, then\n                # as directory, then fall back to displaying a 404.\n                try_files $uri $uri\/ =404;\n        }\n        location = \/.well-known\/atproto-did {\n                default_type text\/plain;\n        }\n        # ... lots of SSL stuff omitted ...\n}\n<\/code><\/pre>\n\n\n\n<p>So basically this tells nginx to try to serve any existing file or fall-back to directory or 404. It forces <code>text\/plain<\/code> for the <code>\/.well-known\/atproto-did<\/code> file, since otherwise it is serves as <code>application\/octet-stream<\/code> which violates the requirements.<\/p>\n\n\n\n<p>Then I used <code>vim<\/code> to simply create the file and validated that the content of the file was accessible correctly via <code>curl<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.dont-panic.cc\/capi\/wp-content\/uploads\/2023\/10\/image.png\"><img loading=\"lazy\" decoding=\"async\" width=\"582\" height=\"289\" src=\"https:\/\/www.dont-panic.cc\/capi\/wp-content\/uploads\/2023\/10\/image.png\" alt=\"\" class=\"wp-image-673\" srcset=\"https:\/\/www.dont-panic.cc\/capi\/wp-content\/uploads\/2023\/10\/image.png 582w, https:\/\/www.dont-panic.cc\/capi\/wp-content\/uploads\/2023\/10\/image-300x149.png 300w\" sizes=\"auto, (max-width: 582px) 85vw, 582px\" \/><\/a><\/figure>\n\n\n\n<p>Looked good, so hit this verify button. And it failed. After a few retries, i decided that maybe it&#8217;s because of the final newline that end of the file? <\/p>\n\n\n\n<p>New approach (note the &#8220;<strong>-n<\/strong>&#8220;!):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>echo -n \"did:plc:njnt2ukwkoljfxnsqsbs5mdm\" > \/var\/www\/cc\/dont-panic\/martin\/.well-known\/atproto-did<\/code><\/pre>\n\n\n\n<p>One click on verify later, Bluesky accepted the handle as verified and I could switch over from my previous user name.<\/p>\n\n\n\n<p>So, looking forward to hearing from you either in the comments here or via Bluesky. <a href=\"https:\/\/bsky.app\/profile\/martin.dont-panic.cc\" data-type=\"link\" data-id=\"https:\/\/bsky.app\/profile\/martin.dont-panic.cc\">Follow me!<\/a> \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>TLDR: Beware that there must be no newline at the end of the .well-known\/atproto-did file and that the content type needs to be text\/plain. echo -n to the rescue instead of vim. I recently received an invite to Bluesky and so far I&#8217;ve enjoyed the experience. Early-day Twitter feeling. Can recommend to check it out &hellip; <a href=\"https:\/\/www.dont-panic.cc\/capi\/2023\/10\/03\/bluesky-with-own-domain-handle-and-well-known-atproto-did\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Bluesky with own domain-handle and .well-known\/atproto-did&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,3],"tags":[251,249,250],"class_list":["post-672","post","type-post","status-publish","format-standard","hentry","category-computer","category-internet","tag-atproto","tag-bluesky","tag-nginx"],"_links":{"self":[{"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/posts\/672","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/comments?post=672"}],"version-history":[{"count":2,"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/posts\/672\/revisions"}],"predecessor-version":[{"id":675,"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/posts\/672\/revisions\/675"}],"wp:attachment":[{"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/media?parent=672"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/categories?post=672"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/tags?post=672"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}