<?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: João Augusto Perin</title>
    <description>The latest articles on DEV Community by João Augusto Perin (@joojscript).</description>
    <link>https://dev.to/joojscript</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%2F661860%2Fae3e1546-a4b8-43f3-bedd-1960f736f434.jpeg</url>
      <title>DEV Community: João Augusto Perin</title>
      <link>https://dev.to/joojscript</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joojscript"/>
    <language>en</language>
    <item>
      <title>So...What are these Decentralized Identifiers?</title>
      <dc:creator>João Augusto Perin</dc:creator>
      <pubDate>Tue, 29 Jul 2025 17:36:23 +0000</pubDate>
      <link>https://dev.to/joojscript/sowhat-are-these-decentralized-identifiers-130l</link>
      <guid>https://dev.to/joojscript/sowhat-are-these-decentralized-identifiers-130l</guid>
      <description>&lt;p&gt;Recently, I took notice of a "new" type of identifier that is being more and more used through many systems nowadays, but, although it comes with a lot of design decisions that may sound revolutionary at first, we need to be careful before thinking anything more of it.&lt;/p&gt;

&lt;p&gt;Let's take a look, today, at the &lt;strong&gt;Decentralized Identifiers&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What are Decentralized Identifiers (DIDs)
&lt;/h2&gt;

&lt;p&gt;Decentralized Identifiers, or &lt;strong&gt;DIDs&lt;/strong&gt;, are a new class of globally unique identifiers that are &lt;strong&gt;cryptographically verifiable&lt;/strong&gt;, &lt;strong&gt;self‑sovereign&lt;/strong&gt;, and &lt;strong&gt;resolvable without a central authority&lt;/strong&gt;. Unlike typical identifiers (email, username, social media handle), which are issued and controlled by a central service provider, DIDs are defined in a way that lets the identity controller &lt;strong&gt;fully own and control the identifier&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A DID has a canonical form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;did:&amp;lt;method&amp;gt;:&amp;lt;method‑specific‑id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example: &lt;code&gt;did:example:123456789abcdefghi&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;example&lt;/code&gt; is the DID method (implementation rules, e.g. &lt;code&gt;did:ion&lt;/code&gt;, &lt;code&gt;did:key&lt;/code&gt;, &lt;code&gt;did:sov&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;method‑specific‑id&lt;/code&gt; is some unique string or public key fingerprint.&lt;/li&gt;
&lt;li&gt;The DID itself can resolve to a &lt;strong&gt;DID document&lt;/strong&gt;—a JSON object that holds public keys, service endpoints, authentication methods, and more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because DIDs are not tied to any central registry, the holder can generate new DIDs freely, rotate keys, and choose where the DID document lives (on a DID network, IPFS, HTTPS, etc.).&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 How DIDs Work (Step by Step)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Creation&lt;/strong&gt;&lt;br&gt;
You generate a key pair (e.g. ed25519). That public key fingerprint becomes your &lt;code&gt;method‑specific‑id&lt;/code&gt;. You choose a DID method, e.g. &lt;code&gt;did:key&lt;/code&gt;, which encodes the public key directly, or &lt;code&gt;did:ion&lt;/code&gt;, which anchors state updates on blockchain-like infrastructure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;DID Document&lt;/strong&gt;&lt;br&gt;
The DID resolves to a &lt;strong&gt;DID Document&lt;/strong&gt; that typically includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;public key(s) for authentication or encryption,&lt;/li&gt;
&lt;li&gt;authentication and assertion methods,&lt;/li&gt;
&lt;li&gt;service endpoints (e.g. &lt;code&gt;service: messaging&lt;/code&gt;, &lt;code&gt;service: vc-storage&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resolution &amp;amp; Verification&lt;/strong&gt;&lt;br&gt;
Clients use a &lt;strong&gt;DID resolver&lt;/strong&gt; for the specific method. They fetch (or verify) the DID document, check cryptographic bindings, and confirm that the public key matches. That guarantees: &lt;em&gt;“this DID corresponds to someone who holds the private key.”&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Authentication &amp;amp; Verifiable Credentials&lt;/strong&gt;&lt;br&gt;
Using DID-based authentication (e.g. using JSON‑LD proof or JWT with DID DID‑Auth), the controller proves ownership by signing a challenge. Receiving systems verify signatures based on the DID document.  &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For Verifiable Credentials, an issuer signs a credential (e.g. a diploma, attestation) using their DID key. The holder stores the credential and later presents proofs, and verifiers check both signature and revocation status using DID resolution or credential registry.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Key Rotation &amp;amp; DID Updates&lt;/strong&gt;&lt;br&gt;
Some DID methods (like &lt;code&gt;did:ion&lt;/code&gt;, &lt;code&gt;did:sov&lt;/code&gt;) support versioned DID documents: you can rotate keys, add or remove public keys. The DID still resolves to the latest document, with history anchored immutably (e.g. on multi-party anchoring networks).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Decentralization &amp;amp; Trust Model&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There's no single root authority leasing identifiers.&lt;/li&gt;
&lt;li&gt;Control comes from &lt;strong&gt;cryptographic proofs&lt;/strong&gt;, not trust in a central issuer.&lt;/li&gt;
&lt;li&gt;The integrity of DID history depends on the method (blockchain‑anchored, distributed ledger, registry, etc.).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🛠️ Use Cases &amp;amp; Practical Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Authentication without passwords
&lt;/h3&gt;

&lt;p&gt;A user generates &lt;code&gt;did:key&lt;/code&gt; on their device. When signing into a service, they sign a challenge using their private key. The service resolves the DID, fetches the public key, verifies the signature—and logs the user in.&lt;br&gt;&lt;br&gt;
&lt;em&gt;No usernames, no passwords, no provider‑centralized identities.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Verifiable Credentials ecosystem
&lt;/h3&gt;

&lt;p&gt;Universities, employers, and governments can issue credentials (degree certificates, licenses, KYC attestations) signed with their DIDs. Holders store them in encrypted wallets, share only necessary proofs with third parties (e.g. “I have a degree, not which major”). The verifier resolves issuer DID, verifies signature, optionally checks revocation.&lt;br&gt;&lt;br&gt;
&lt;em&gt;Privacy-preserving, portable, and user‑controlled.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Decentralized Web of Trust &amp;amp; social networks
&lt;/h3&gt;

&lt;p&gt;In peer‑to‑peer networks, each node publishes their DID document with service endpoints and verification keys. Peers can exchange signed messages or verify membership without relying on central servers.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. IoT device identity
&lt;/h3&gt;

&lt;p&gt;IoT devices can hold &lt;code&gt;did:ion&lt;/code&gt;‑style identifiers. When a sensor sends data to a network, it signs readings—automated systems verify the sender’s DID, its key authority, and optionally check that it was registered at device minting time.&lt;/p&gt;
&lt;h3&gt;
  
  
  5. Supply chain provenance
&lt;/h3&gt;

&lt;p&gt;Brands allocate DIDs to shipments or batches. Each actor writes attested events (manufacturing, shipping, storage) tied to those DIDs. Verifiers can query events linked to the item’s DID history, confirming origin and transit chain.&lt;/p&gt;


&lt;h2&gt;
  
  
  ⚙️ Implementation Patterns &amp;amp; Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;DID methods&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;did:key&lt;/code&gt;: simplest, public key encoded as DID, no blockchain or registry.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;did:ion&lt;/code&gt; (built on Sidetree): supports updates, anchored on public ledger.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;did:sov&lt;/code&gt;: part of Hyperledger Indy, often used in enterprise credential networks.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DID Document structure&lt;/strong&gt;&lt;br&gt;
Standard JSON‑LD structure with keys, authentication, service endpoints.&lt;br&gt;&lt;br&gt;
Resolution may return historical versions or meta‑information depending on the method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Libraries &amp;amp; tooling&lt;/strong&gt;&lt;br&gt;
Tools like &lt;code&gt;did‑kit&lt;/code&gt;, &lt;code&gt;indy‑sdk&lt;/code&gt;, &lt;code&gt;veramo&lt;/code&gt;, &lt;code&gt;trinsic&lt;/code&gt;, or &lt;code&gt;ssi‑web&lt;/code&gt; implement DID management, issuance, storage, resolution, and credential flows in languages like TypeScript, Rust, and Go.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security &amp;amp; key management&lt;/strong&gt;&lt;br&gt;
Local key stores, hardware security modules (HSMs), or secure enclaves hold private keys. Seed phrases or recovery methods are critical for user control.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Interoperability considerations&lt;/strong&gt;&lt;br&gt;
Credential formats (W3C VC), proof standards (JSON‑LD, BBS+, JWT), DID resolver compatibility—all matter for systems that interact across networks.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🧾 Pros and Cons
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Self‑sovereign identity&lt;/strong&gt;: users own their identifiers and data.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interoperable standard&lt;/strong&gt;: W3C‑recognized, cross‑platform.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verifiable and portable&lt;/strong&gt;: cryptographic assurance without central providers.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privacy‑preserving&lt;/strong&gt;: selective disclosure, zero‑knowledge proof support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Method fragmentation&lt;/strong&gt;: many DID methods exist, and not all are interoperable.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure complexity&lt;/strong&gt;: resolution, key rotation, revocation require external networks or registries.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usability challenges&lt;/strong&gt;: key management, recovery, wallet compatibility—not as seamless as centralized login flows.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trust bootstrapping&lt;/strong&gt;: verifying issuer trust (e.g. a university DID) may still rely on registries or off‑chain trust lists.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  💻 Pseudo-code
&lt;/h2&gt;

&lt;p&gt;Here we'll have some basic examples of usage, and some diagrams to help understand the usage of these DIDs:&lt;/p&gt;
&lt;h3&gt;
  
  
  DID Authentication Flow
&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%2Fwlf3u45baxkpv5y8nafm.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%2Fwlf3u45baxkpv5y8nafm.png" alt="DID Authentication Flow" width="800" height="485"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Verifier generates a random challenge&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;challenge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateRandomString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nf"&gt;sendToClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Client signs the challenge with their private key&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;privateKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Verifier resolves the DID document&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;didDocument&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;resolveDID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientDID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;publicKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extractPublicKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;didDocument&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Verifier checks the signature&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isValid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;verifySignature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;publicKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;isValid&lt;/span&gt; &lt;span class="nf"&gt;grantAccess&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Creating a DID Key
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Generate a keypair&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keypair&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateKeyPair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;algorithm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ed25519&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Encode public key in multibase + multicodec format&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encodedKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;encodeMultibase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keypair&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publicKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Construct the DID&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;did&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;did:key:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;encodedKey&lt;/span&gt;

&lt;span class="c1"&gt;// Create a DID document&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;didDocument&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@context&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.w3.org/ns/did/v1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;did&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;publicKey&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;did&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#key-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ed25519VerificationKey2018&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;controller&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;did&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;publicKeyMultibase&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;encodedKey&lt;/span&gt;
  &lt;span class="p"&gt;}],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;authentication&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;did&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#key-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Resolving a DID
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Generic DID resolver&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;resolveDID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;did&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extractMethodFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;did&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// e.g. "key", "ion", "web"&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resolver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getResolverForMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;resolver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;did&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Verifiable Credential Issuance &amp;amp; Verification
&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%2Fn1k801rjbe2rzvjcz6ll.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%2Fn1k801rjbe2rzvjcz6ll.png" alt="Verifiable Credential Issuance &amp;amp; Verification" width="800" height="485"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Verifier checks integrity and authenticity of a credential&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;credential&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;receiveCredential&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// 1. Resolve issuer DID to get public key&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;issuerDID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;issuer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;issuerDoc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;resolveDID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;issuerDID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;issuerKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extractPublicKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;issuerDoc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 2. Verify the signature&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isValid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;verifySignature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;proof&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;issuerKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;isValid&lt;/span&gt; &lt;span class="nf"&gt;acceptCredential&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;rejectCredential&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🧠 Tips for Real Implementations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use Well-known libraries like &lt;code&gt;didkit&lt;/code&gt;, &lt;code&gt;veramo&lt;/code&gt;, or &lt;code&gt;@identity.com/credentials&lt;/code&gt; for implementation.&lt;/li&gt;
&lt;li&gt;Prefer &lt;code&gt;did:key&lt;/code&gt; for ephemeral, short-lived identities.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;did:ion&lt;/code&gt; or &lt;code&gt;did:web&lt;/code&gt; for long-lived, public identities.&lt;/li&gt;
&lt;li&gt;Use credential formats like JSON-LD for maximum interoperability.&lt;/li&gt;
&lt;li&gt;Consider key rotation and revocation strategies early.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✅ Takeaways
&lt;/h2&gt;

&lt;p&gt;DIDs are a thoughtful re‑imagining of digital identity—rooted in cryptographic verification and user control, decoupled from centralized authorities. They enable flows like password‑less authentication, verifiable credentials, and IoT provenance that are portable and privacy‑aware.&lt;/p&gt;

&lt;p&gt;Yet, despite their potential, real‑world adoption still faces friction: fragmentation of methods, key recovery UX, and ecosystem trust models. As with variance and authentication systems you've written about, it's essential to look under the hood—understand cryptographic anchors, resolution design, and architectural trade‑offs—before embracing the hype.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>architecture</category>
      <category>learning</category>
    </item>
    <item>
      <title>What are Blockchain Oracles?</title>
      <dc:creator>João Augusto Perin</dc:creator>
      <pubDate>Tue, 29 Jul 2025 17:11:16 +0000</pubDate>
      <link>https://dev.to/joojscript/what-are-blockchain-oracles-3pki</link>
      <guid>https://dev.to/joojscript/what-are-blockchain-oracles-3pki</guid>
      <description>&lt;p&gt;At the core of blockchains lies deterministic, self‑contained code execution: smart contracts run on consensus nodes using on‑chain data only. But most real‑world logic depends on external events—asset prices, weather data, identity verification—and blockchains don’t inherently have access to that. That is where oracles come in. They serve as gateways between off‑chain data and on‑chain logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 What an Oracle is
&lt;/h2&gt;

&lt;p&gt;In short, the bridge between on‑chain trust and off‑chain reality.&lt;/p&gt;

&lt;p&gt;A blockchain oracle is a trusted data provider that fetches real-world data, submits it to the blockchain, and ensures that smart contracts can verify and act upon that information. It’s not just a price feed—it can encapsulate:&lt;/p&gt;

&lt;p&gt;Data retrieval: reading external APIs like market data, weather, flight logs, and IoT sensors.&lt;/p&gt;

&lt;p&gt;Data validation and aggregation: from multiple sources to reduce error or manipulation.&lt;/p&gt;

&lt;p&gt;On‑chain reporting: pushing that data into smart contracts in a verifiable fashion.&lt;/p&gt;

&lt;p&gt;Custom triggers: e.g., “if event X happens off‑chain, execute that function on‑chain.”&lt;/p&gt;

&lt;p&gt;Without oracles, contracts cannot reason about events outside their cryptographically sealed context.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔄 How blockchain oracles work (architecturally)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Smart contract requests&lt;/strong&gt;&lt;br&gt;
A contract emits a request (e.g., “Request price of ETH/USD at block N”), often via an on‑chain transaction.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Oracle node fetches off‑chain data&lt;/strong&gt;&lt;br&gt;
The oracle listens for request events, then queries external data sources (APIs, web scraping, IoT streams, etc.).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data aggregation and transformation&lt;/strong&gt;&lt;br&gt;
The oracle may fetch multiple sources, compute a median or weighted average, attach timestamps, and check signatures.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Submission on‑chain&lt;/strong&gt;&lt;br&gt;
The oracle submits the cleaned data back as a transaction, calling a callback or fulfillment function in the contract.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Verification by contract&lt;/strong&gt;&lt;br&gt;
The contract checks the oracle’s submission (e.g., are signatures valid? Did the timestamp fit expectations?), then uses the data to execute logic (e.g., release funds, trigger bets, adjust collateral).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Optional&lt;/em&gt; reputation or staking layer&lt;/strong&gt;&lt;br&gt;
Many oracle networks incorporate staking or slashing: nodes stake tokens and can be penalized for sending bad data, promoting honesty.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧱 Types of Oracles
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Centralized Oracles&lt;/strong&gt;&lt;br&gt;
A single data provider (e.g., using one API) pushing data to a contract. Simple, but introduces single‑point‑of‑failure and trust risks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Decentralized Oracle Networks (DONs)&lt;/strong&gt;&lt;br&gt;
Protocols like Chainlink, Band Protocol, and Pyth Network — each uses multiple independent nodes, aggregates data, and makes the result tamper‑resistant.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Inbound vs Outbound Oracles&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inbound: off‑chain → on‑chain (e.g., price feeds).
&lt;/li&gt;
&lt;li&gt;Outbound: smart contracts → off‑chain, for event notifications or triggering workflows (e.g, Chainlink Keepers).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hardware-backed oracles (trusted execution environments)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Fetching real-world data with confidential computing (e.g., Intel SGX attested relays) when data privacy or tamper-resistance matters.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Use cases: practical examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. DeFi price feeds
&lt;/h3&gt;

&lt;p&gt;Automated market maker perks, lending protocols, oracles supply &lt;strong&gt;ETH/USD&lt;/strong&gt;, &lt;strong&gt;BTC/USD&lt;/strong&gt;, &lt;strong&gt;stablecoin peg data&lt;/strong&gt; to calculate collateral ratios or trigger liquidations. Aggregated feeds from multiple oracles ensure reliability.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Prediction markets &amp;amp; contingency payouts
&lt;/h3&gt;

&lt;p&gt;Protocols like Augur or UMA rely on oracles to confirm off‑chain events (election results, sports scores, weather thresholds) to settle contracts and payouts.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Insurance and parametric products
&lt;/h3&gt;

&lt;p&gt;Weather oracles feed rainfall or temperature data into smart contracts. If certain thresholds are met (e.g., drought, storm), the contract automatically pays claims.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Dynamic gaming &amp;amp; NFTs
&lt;/h3&gt;

&lt;p&gt;Games that depend on outside events—say, token rewards tied to real‑world sports outcomes, or generative NFTs that evolve based on time-of-day or temperature—can use oracles to retrieve that external data.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Hybrid smart contracts
&lt;/h3&gt;

&lt;p&gt;Oracles connect on‑chain contracts with off‑chain business logic. For example, a supply‑chain platform might let a contract request shipping data from an external logistics system, with the oracle retrieving and reporting it on‑chain.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Implementation insight (tech stack patterns)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ethereum + Chainlink example&lt;/strong&gt;&lt;br&gt;
A Solidity contract imports an interface like &lt;code&gt;ChainlinkClient&lt;/code&gt;, requests a job that calls an API (e.g. &lt;code&gt;"get": "https://api.exchange/symbol/ETHUSD"&lt;/code&gt;), provides a path (e.g. JSON &lt;code&gt;"price"&lt;/code&gt;), and gets back the value through &lt;code&gt;fulfill&lt;/code&gt; callback.&lt;br&gt;&lt;br&gt;
Chainlink nodes aggregate across multiple APIs, sign the result, and call your contract’s &lt;code&gt;fulfill&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Aggregation logic&lt;/strong&gt;&lt;br&gt;
Many oracles compute statistics like median, trimmed mean, or weighted average before submission—similar to how a blog post on variance and standard deviation explained computing spread and average: aggregate multiple values, compute mean and variance to identify outliers, then select a robust central value (&lt;a href="https://www.geeksforgeeks.org/javascript/how-to-get-the-standard-deviation-of-an-array-of-numbers-using-javascript/" rel="noopener noreferrer"&gt;geeksforgeeks.org&lt;/a&gt;, &lt;a href="https://library.soton.ac.uk/variance-standard-deviation-and-standard-error" rel="noopener noreferrer"&gt;library.soton.ac.uk&lt;/a&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Security considerations&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;multiple independent data sources&lt;/strong&gt; to mitigate API outage or manipulation.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staking and incentives&lt;/strong&gt;: Oracle nodes stake crypto and lose it if they submit false data.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data freshness and TTLs&lt;/strong&gt;: contracts should reject stale data.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Oracle reputation&lt;/strong&gt;: Many Oracle networks track node performance.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧾 Pros and Cons
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enables rich smart‑contract logic tied to real-world events
&lt;/li&gt;
&lt;li&gt;Automation: no human intervention once set up
&lt;/li&gt;
&lt;li&gt;Transparency: data provenance can be audited
&lt;/li&gt;
&lt;li&gt;Decentralization (in network variants) reduces manipulation risk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trust assumptions&lt;/strong&gt;: Relying on off‑chain data introduces risk
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Costs&lt;/strong&gt;: requesting data incurs gas and oracle‑node fees
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latency&lt;/strong&gt;: off‑chain fetch and on‑chain confirmation take time—less suitable for ultra-low‑latency needs
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complex error handling&lt;/strong&gt;: stale data, API failures, malicious or misbehaving nodes, all must be handled&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✅ Takeaways
&lt;/h2&gt;

&lt;p&gt;Blockchain oracles are the &lt;strong&gt;necessary middle layer&lt;/strong&gt; that let smart contracts interact with the physical world. They translate off-chain realities into on-chain events in a verifiable way. Well-designed oracle networks—using multiple nodes, aggregation, staking, data freshness checks—let decentralized applications be &lt;strong&gt;secure, predictable, and powerful&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>crypto</category>
      <category>tech</category>
    </item>
    <item>
      <title>Docker DNS: The Odyssey</title>
      <dc:creator>João Augusto Perin</dc:creator>
      <pubDate>Mon, 27 Sep 2021 14:51:00 +0000</pubDate>
      <link>https://dev.to/joojscript/docker-dns-the-odyssey-39dc</link>
      <guid>https://dev.to/joojscript/docker-dns-the-odyssey-39dc</guid>
      <description>&lt;p&gt;Well, well, well...How could I imagine that configuring a VPN would not be so easy? Hahahaha, ok, I'll explain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backstory (feel completely free to skip it right away)
&lt;/h2&gt;

&lt;p&gt;Recently I changed my workstation, I used to code on a Macbook Air before, but now I moved to a desktop, and because of it, I needed to configure my VPN all again, no big deal.&lt;/p&gt;

&lt;p&gt;I'm currently using &lt;a href="https://www.deepin.org/en/"&gt;Deepin&lt;/a&gt; as my distro, and I did not have much problems &lt;strong&gt;until today&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem itself
&lt;/h2&gt;

&lt;p&gt;If you have skipped the last part, just to let you know, I need to configure a VPN.&lt;/p&gt;

&lt;p&gt;"Ok, but what does this have with docker?" - you may ask.&lt;/p&gt;

&lt;p&gt;Well, the VPN setup came up alright, I use &lt;a href="https://openvpn.net/"&gt;OpenVPN&lt;/a&gt; and it works just fine.&lt;/p&gt;

&lt;p&gt;But the problem came when I tried to access a private address, visible only to the ones with VPN access, and I could not, even though I was connected, but why?&lt;/p&gt;

&lt;p&gt;Digging in, I realized that the IP of this specific host resolved on chrome to the page I wanted, so it was a &lt;strong&gt;DNS problem&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The .ovpn file
&lt;/h2&gt;

&lt;p&gt;At first, I had a &lt;em&gt;.ovpn&lt;/em&gt; file, that looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;client
dev tun
resolv-retry infinite
nobind
persist-key
persist-tun
proto udp
cipher zzzz
comp-lzo
verb 3
remote xxxx yyyy
#ncp-disable
auth SHA512
#float
remote-cert-tls server
#ns-cert-type server
key-direction 1
&amp;lt;ca&amp;gt;
[..]
&amp;lt;/ca&amp;gt;
&amp;lt;tls-auth&amp;gt;
[..]
&amp;lt;/tls-auth&amp;gt;
&amp;lt;cert&amp;gt;
[..]
&amp;lt;/cert&amp;gt;
&amp;lt;key&amp;gt;
[..]
&amp;lt;/key&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the file above always worked well, I already used this file on Windows, Ubuntu and MacOs, always without any problem.&lt;/p&gt;

&lt;p&gt;but this time was different, and after discovering the reason why it was not working (the dns thing), I started searching all over the internet for solutions, even though I have nearly zero knowledge of how things work with docker domain name resolution, but needed it working.&lt;/p&gt;

&lt;h2&gt;
  
  
  The attempts
&lt;/h2&gt;

&lt;p&gt;I changed my .ovpn multiple times, to different values, parameters, options, and nothing worked. At the point, i was already thinking on changing my distro.&lt;/p&gt;

&lt;p&gt;Also, I have to mention that, a friend of mine, a Deepin user as well, told me that he could not use OpenVPN at all on his GUI on Deepin, although by the CLI it always worked fine.&lt;/p&gt;

&lt;p&gt;We realize that OpenVPN already ships with a specific script, named "update-resolv-conf", under &lt;code&gt;/etc/openvpn/&lt;/code&gt;, but it was not called in my OpenVPN file, and when I did it, it did not work. &lt;/p&gt;

&lt;p&gt;Then, the closest I got to actually getting things working, was to redirect the up and down scripts of the .ovpn file to a custom script (provided by the guy on stack-overflow (trustworthy, I know)):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;up /etc/openvpn/update-systemd-resolved
down /etc/openvpn/update-systemd-resolved
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but, along with it, I had to add some lines above it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;script-security 2
dhcp-option DNS &amp;lt;DNS-IP&amp;gt;
dhcp-option DOMAIN &amp;lt;DNS-DOMAIN-NAME&amp;gt;
dhcp-option DOMAIN-ROUTE .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It had worked, I could access the domain I was trying without using its IP. So NICE!!! that's it?&lt;/p&gt;

&lt;h2&gt;
  
  
  Oh, no...
&lt;/h2&gt;

&lt;p&gt;So, today I was getting the environment running, and, not to get much deeper here, we had a service which need connection with one of our hosts (and do it by connecting to its domain). But guess what? The docker container was not finding it!&lt;/p&gt;

&lt;p&gt;I &lt;code&gt;docker exec -it &amp;lt;CONTAINER-NAME&amp;gt; sh&lt;/code&gt; inside it, so I could try with my own hands, and it really does not work.&lt;/p&gt;

&lt;p&gt;Searching for what could have happened, I got to the final step:&lt;/p&gt;

&lt;h2&gt;
  
  
  The resolv.conf file
&lt;/h2&gt;

&lt;p&gt;To be brief, &lt;a href="https://man7.org/linux/man-pages/man5/resolv.conf.5.html"&gt;resolv.conf&lt;/a&gt;, is a file located in &lt;code&gt;/etc/resolv.conf&lt;/code&gt;, which, on official linux man page words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The file is designed to be human readable and contains a list of&lt;br&gt;
       keywords with values that provide various types of resolver&lt;br&gt;
       information.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and now, if you already got it, congrats, if not, remember that user-customized script that I mentioned earlier? And the one provided by openvpn?&lt;/p&gt;

&lt;p&gt;So, they're both meant to resolve the DNS, but the one provided by openvpn, &lt;strong&gt;also, include the new resolved ip's into resolv.conf file&lt;/strong&gt;, making it visible to the entire system (local, and docker).&lt;/p&gt;

&lt;p&gt;So, at last, probably what happened was, chronologically:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;.ovpn file did not call the script (in other versions of openvpn it does it automatically).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When I called it by hand, I did not have the &lt;code&gt;dhcp option&lt;/code&gt; params on my .ovpn file (again, probably other versions and distributions of OpenVPN do it automatically, but that's not my case, unfortunately).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I added the scripts and the lines with &lt;code&gt;dhcp option&lt;/code&gt; definition, and had it working, but only for my machine, not the containers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When I had the correct update to &lt;code&gt;/etc/resolv.conf&lt;/code&gt; file, the containers started seeing the domain.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;For the record, my version of OpenVPN was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OpenVPN 2.4.7 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Sep  1 2020
library versions: OpenSSL 1.1.1d  10 Sep 2019, LZO 2.10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But then, as a attempt, I updated my OpenVPN to version 3, it was not that easy, there were some compatibility issues between versions of Debian and Deepin, but I could workaround over it.&lt;/p&gt;

&lt;p&gt;When I updated to OpenVPN 3, everything worked just fine, automatically, with the original file, and everything made sense again. It &lt;strong&gt;really&lt;/strong&gt; does everything automatically, and that's why I had never had problems with Windows, or Ubuntu or MacOs, because all of these implementations uses v3 o OpenVPN (Ubuntu not necessarily, but I used in the time).&lt;/p&gt;

&lt;p&gt;By the way, if you look into the downloads page, you'll see that the GUI world of OpenVPN (the one used in MacOs and Windows), are called "OpenVPN Connect v3" by the official website, maybe you now know why is it&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q1GEBYVm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dnyaxv6vb6czrd8qqchd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q1GEBYVm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dnyaxv6vb6czrd8qqchd.png" alt="image"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Unfortunately, my last move was trying to integrate OpenVPN v3 with the Network Manager from Deepin, to use it in the GUI, which would be much more convenient, but I came across &lt;a href="https://github.com/OpenVPN/openvpn3-linux/issues/46#issuecomment-843172145"&gt;this issue&lt;/a&gt;, as the comment I highlighted indicates, there is no such integration, at least at the time this post is being made.&lt;/p&gt;

&lt;p&gt;Hope you liked, and hope it can help you,&lt;br&gt;
Thanks for reading!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>docker</category>
      <category>container</category>
      <category>dns</category>
    </item>
    <item>
      <title>Passwordless: a note on Authentication</title>
      <dc:creator>João Augusto Perin</dc:creator>
      <pubDate>Sat, 10 Jul 2021 18:36:21 +0000</pubDate>
      <link>https://dev.to/joojscript/passwordless-a-note-on-authentication-2on5</link>
      <guid>https://dev.to/joojscript/passwordless-a-note-on-authentication-2on5</guid>
      <description>&lt;p&gt;Well passwords have been here for a while now, and, as when it was a trend, or the basic go-to option for authentication, it was already questioned about, but not how it is nowadays. Password today can be ~easily~ hacked, or hijacked, or just brute-forced guessed.&lt;/p&gt;

&lt;p&gt;As you may think, the main reason why they still here is because they're one of the easiest solutions on authentication of someone or something.&lt;/p&gt;

&lt;p&gt;But if you want to be more secure (and more user-frindly, perhaps), &lt;strong&gt;passwordless starts coming into play&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Since I started using &lt;a href="https://asciinema.org"&gt;asciinema&lt;/a&gt;, I have been always thinking on how they solved so well the problem on authentication, something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Site: "Well, you want to create an account?"
User: "Yes, I do."
Site: "So give me your e-mail, please."
User: "example@email.com, there you go."
Site: "Okay, get your access there."
User: "That's it?"
Site: "Yeah, why not?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was sufficient to blow my mind.&lt;/p&gt;

&lt;p&gt;'Cause it is &lt;strong&gt;REALLY&lt;/strong&gt; simple, as it could (shouldn't maybe, in some cases) be.&lt;/p&gt;

&lt;p&gt;And that's basically it, every time you come back into the site, and put your e-mail on login, the system will recognize that you're already registered, and say again: "Ok, get your access into your e-mail".&lt;/p&gt;

&lt;p&gt;Maybe, we should go trough some password issues right now, just so we can get to know some things we're avoiding doing these kind of things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users often create weak passwords that are vulnerable to phishing attacks.&lt;/li&gt;
&lt;li&gt;Vulnerable to brute-force attacks.&lt;/li&gt;
&lt;li&gt;Users often reuse the same authentication credentials on different accounts, leading to Domino-effect.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and that is just three of the first things that comes into mind when we start talking about passwords, I'm not talking about possible issues on the implementations itself, it can occur in cryptography process, or in safe storaging, or any other part of the whole process.&lt;/p&gt;

&lt;p&gt;Now, think about just changing the whoooooole work of doing all these steps, into the work of generating a token, and sending it through E-mail, to your user. It can serve as an always-confirm-user-account pass as well!!&lt;/p&gt;

&lt;p&gt;I'm not saying passwordless authentication is always based on contacting user by e-mail, it can be made in infinite ways, I have already seen Hardware-related authentication, like &lt;strong&gt;really, literally&lt;/strong&gt; keys, to a system.&lt;/p&gt;

&lt;p&gt;I'm just starting the conversation here, what do you think? Did you like the idea? Let me know! 😄&lt;/p&gt;

</description>
      <category>authentication</category>
      <category>it</category>
      <category>programming</category>
    </item>
    <item>
      <title>Variance &amp; Standard Deviation 101</title>
      <dc:creator>João Augusto Perin</dc:creator>
      <pubDate>Mon, 05 Jul 2021 16:45:32 +0000</pubDate>
      <link>https://dev.to/joojscript/variance-standard-deviation-101-2jec</link>
      <guid>https://dev.to/joojscript/variance-standard-deviation-101-2jec</guid>
      <description>&lt;p&gt;Well, Hi there! This is my first Dev.to post, and I'm really excited to begin here! 😁&lt;/p&gt;

&lt;p&gt;Perhaps, you already know me from &lt;a href="https://joaoaugustoperin.tumblr.com"&gt;my Tumblr&lt;/a&gt;, or &lt;a href="https://medium.com/@joojscript"&gt;my Medium&lt;/a&gt;. But nice, and original content will be written here, so take a seat!&lt;/p&gt;

&lt;p&gt;To start off, I decided to share a little piece of mathematical knowledge, that, although simple, it is very common to forget, or simply don't come across. But is very useful, and, if you want to follow the path of machine learning, for instance, it is a &lt;strong&gt;must know basic concept&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So let's jump in!&lt;/p&gt;

&lt;p&gt;O.b.s: I'm assuming you already know the base concepts of statistics. Such as average, mode and median.&lt;/p&gt;

&lt;h2&gt;
  
  
  Variance
&lt;/h2&gt;

&lt;p&gt;You can think variance, just like the average means like the "center" of the data, variance can mean how the data actually behaves around that "center".&lt;/p&gt;

&lt;p&gt;For instance, let's take the mean of these table, which show how many hours of sleep Greg had last week:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Week day&lt;/th&gt;
&lt;th&gt;Hours Slept&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Monday&lt;/td&gt;
&lt;td&gt;7 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tuesday&lt;/td&gt;
&lt;td&gt;8 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wednesday&lt;/td&gt;
&lt;td&gt;6 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thursday&lt;/td&gt;
&lt;td&gt;0 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Friday&lt;/td&gt;
&lt;td&gt;7 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Saturday&lt;/td&gt;
&lt;td&gt;7 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sunday&lt;/td&gt;
&lt;td&gt;10 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This data gives as a average of: &lt;strong&gt;7,6 hours slept per night&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But, let's change the question here, and if we want to know ˜how constant˜ is the sleeping behavior of Greg?&lt;/p&gt;

&lt;p&gt;So, now we want to know, having an average behavior of 7,6 hour slept/night, how constant was these hours?&lt;/p&gt;

&lt;p&gt;Variance is defined by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Σ(average - x)² / n 

-&amp;gt; x being the hours slept.
-&amp;gt; n being the amount of data.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, the example above would evaluate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(7-6.42)² + (8-6.42)² + (6-6.42)² + (0-6.42)² + (7-6.42)² + (7-6.42)² + (10-6.42)²
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which would result: &lt;code&gt;10.38&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Standard Deviation
&lt;/h2&gt;

&lt;p&gt;Now that you understood &lt;strong&gt;variance&lt;/strong&gt;, the standard deviation, is used to minimize the noise made by the ²'s on variance's formula.&lt;/p&gt;

&lt;p&gt;Calculate de SD by: &lt;code&gt;sqrt(variance)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In our case, it will be: &lt;strong&gt;3.22&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you're a little advanced in Maths, you can think of variance as the value of a function y, and the SD being the derivative of the same function. 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  Foreword
&lt;/h2&gt;

&lt;p&gt;Both have lots of use-cases, that I pretend to bring here on future posts. Hope it helps! 😁&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>maths</category>
      <category>statistic</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
