<?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: Ayman Patel</title>
    <description>The latest articles on DEV Community by Ayman Patel (@aymanapatel).</description>
    <link>https://dev.to/aymanapatel</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%2F122490%2F721bb366-fcd8-401c-be64-e59e4bb7242e.jpg</url>
      <title>DEV Community: Ayman Patel</title>
      <link>https://dev.to/aymanapatel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aymanapatel"/>
    <language>en</language>
    <item>
      <title>HTMX for Python: Introducing FastHTML</title>
      <dc:creator>Ayman Patel</dc:creator>
      <pubDate>Tue, 08 Apr 2025 06:26:42 +0000</pubDate>
      <link>https://dev.to/aymanapatel/htmx-for-python-introducing-fasthtml-37hm</link>
      <guid>https://dev.to/aymanapatel/htmx-for-python-introducing-fasthtml-37hm</guid>
      <description>&lt;p&gt;🔥 A new minimalistic Python implementation to creating web apps!&lt;/p&gt;

&lt;p&gt;FastHTML, which can be started with a 6-line Python script. But can scale in creating complex web applications with no full-page reloads thanks to HTMX.&lt;/p&gt;

&lt;p&gt;🚀 It is small and fast thanks to leveraging:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;HTMX: For enhancing HTML to bring rich client applications. HTMX also allows to bring HATEOAS as first-class citizen for end-to-end applications perspective.
&lt;/li&gt;
&lt;li&gt;ASGI: Implementing the ASGI spec for concurrency. ASGI spec is implemented by using Uvicorn and Starlette.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;🏢 Deployment Targets:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Vercel
&lt;/li&gt;
&lt;li&gt;Railway
&lt;/li&gt;
&lt;li&gt;Hugging face and more&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📖 Readings:&lt;br&gt;&lt;br&gt;
FastHTML &lt;a href="https://fastht.ml/" rel="noopener noreferrer"&gt;https://fastht.ml/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
FastHTML Docs: &lt;a href="https://docs.fastht.ml/" rel="noopener noreferrer"&gt;https://docs.fastht.ml/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>htmx</category>
      <category>python</category>
    </item>
    <item>
      <title>Upgrading Java and Spring without hassle</title>
      <dc:creator>Ayman Patel</dc:creator>
      <pubDate>Tue, 08 Apr 2025 06:22:34 +0000</pubDate>
      <link>https://dev.to/aymanapatel/upgrading-java-and-spring-without-hassle-3530</link>
      <guid>https://dev.to/aymanapatel/upgrading-java-and-spring-without-hassle-3530</guid>
      <description>&lt;p&gt;🤔 Want to upgrade Java, Spring Boot versions is a methodical way&lt;/p&gt;

&lt;p&gt;There is a platform for that!&lt;/p&gt;

&lt;p&gt;💡 Moderne's OpenRewrite platform helps with managing complexities in upgrading your Java based projects&lt;/p&gt;

&lt;p&gt;Some common use cases include:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Upgrading to Java 17
&lt;/li&gt;
&lt;li&gt;Upgrading Spring Boot 2 to Spring Boot 3&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;🙋Why a tool?&lt;br&gt;&lt;br&gt;
Knowing the API changes in libraries for every dependency is difficult. Also, a lot of time can be wasted in a particular solution that does not work well with a particular dependency.&lt;/p&gt;

&lt;p&gt;🔧How does it work?&lt;/p&gt;

&lt;p&gt;You can import custom recipes as Maven/Gradle task and run them.&lt;br&gt;&lt;br&gt;
For example, you want to migrate from JUnit 4 to JUnit 5, you can import a recipe for it in Gradle 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;activeRecipe("org.openrewrite.java.testing.junit5.JUnit5BestPractices")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And run the gradle task:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gradlew rewriteRun
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since these recipes are chainable, you can add steps to make code changes incrementally.&lt;br&gt;&lt;br&gt;
Other features include:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Writing your own custom &lt;a href="https://docs.openrewrite.org/authoring-recipes/recipe-development-environment" rel="noopener noreferrer"&gt;recipes&lt;/a&gt; for your use-case
&lt;/li&gt;
&lt;li&gt;Dashboard to track the recipes done in your project to track your level of completion of version migration.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📖 Resources:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Moderne's site: &lt;a href="https://www.moderne.io/2" rel="noopener noreferrer"&gt;https://www.moderne.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OpenRewrite recipes: &lt;a href="https://docs.openrewrite.org/" rel="noopener noreferrer"&gt;https://docs.openrewrite.org/&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>springboot</category>
    </item>
    <item>
      <title>ABCs of Databases</title>
      <dc:creator>Ayman Patel</dc:creator>
      <pubDate>Sun, 14 Jan 2024 16:39:17 +0000</pubDate>
      <link>https://dev.to/aymanapatel/abcs-of-databases-439f</link>
      <guid>https://dev.to/aymanapatel/abcs-of-databases-439f</guid>
      <description>&lt;p&gt;When we talk about creating APIs with a database for storage; we always think database to be a storage layer which would do its job of doing CRUD operations. But their is a unconscious belief of the API to be single user, single transaction. Even if we think that multiple simultaneous read/writes happen; we assume that data will be in the state that we want. But there are a lot of nuances in how data gets persisted. In order to know about this; there are several topics that need to be covered. These could be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;ABC of database:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What &lt;strong&gt;Transaction Isolation Levels&lt;/strong&gt; is configured at database? What is impact of consistency vs latency with these settings?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Queries planner and Execution&lt;/strong&gt; : How does your query formed by your database affecting the performance of the system&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All these are just high level questions which need to be seen in depth. The first point (i.e ABC of Database) is the starting point to understand the rest of the points; which will be the focus of this blog.&lt;/p&gt;

&lt;h1&gt;
  
  
  ABCs of Database
&lt;/h1&gt;

&lt;p&gt;Just putting the acronym out there:&lt;/p&gt;

&lt;p&gt;| Acronym | 1st | 2nd | 3rd | 4th |&lt;br&gt;
| ACID | Atomicity | Consistency | Isolation | Durability |&lt;br&gt;
| BASE | Basic ... | ... Availability | Soft State | Eventual Consistency |&lt;br&gt;
| CAP | Consistency | Availability | Partition-tolerance |&lt;/p&gt;

&lt;h1&gt;
  
  
  ACID
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--832xSvK5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249498944/2c94a09d-9982-40ef-99e3-c40b78f740c9.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--832xSvK5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249498944/2c94a09d-9982-40ef-99e3-c40b78f740c9.jpeg" alt="" width="394" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1.a. Atomicity
&lt;/h2&gt;

&lt;p&gt;It states that transaction has started; it should either be completed or rolled-back if an error occurs. In DB terms; either transaction should be &lt;code&gt;COMMITTED&lt;/code&gt; or &lt;code&gt;ABORTED&lt;/code&gt; This mechanism is achieved by&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;REDO/UNDO mechanisms&lt;/strong&gt; such as REDO/UNDO logs to bring data to the correct atomic state etc&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shadow Paging&lt;/strong&gt; It follows &lt;strong&gt;Copy-on-write&lt;/strong&gt; mechanism where the parent process forks and creates a &lt;strong&gt;shadow page&lt;/strong&gt; for &lt;em&gt;uncommitted transaction&lt;/em&gt; which is either: F&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;All in or Nothing&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1.b. Consistency
&lt;/h2&gt;

&lt;p&gt;This rule is little bit confusing. Especially when you pair up with BASE(Eventual consistency) and CAP. In spite of confusion; Consistency from ACID is the clear and most thought out definition out of the 3 (ACID, BASE and CAP) acronyms. It states that once database starts the transaction consistently, it should end consistently. Consistency is enforced by Applications with the Integrity Constraints.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Transaction starts in Consistent Manner; And Ends in Consistent Manner(All Integrity constraints are followed)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Consistency is enforced by &lt;strong&gt;integrity constraints&lt;/strong&gt;. This could be Primary Key, or Constraints such as Foreign Key, &lt;code&gt;NULL&lt;/code&gt; constratints, &lt;code&gt;CHECK&lt;/code&gt; value constraints such as &lt;code&gt;ACCOUT&amp;gt;=100&lt;/code&gt; etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.c. Isolation
&lt;/h2&gt;

&lt;p&gt;It states the transactions should be isolated from each other.&lt;/p&gt;

&lt;p&gt;For example; Given Bank Account has &lt;em&gt;100$&lt;/em&gt; , When Alice has a card that they withdraw &lt;em&gt;25$&lt;/em&gt; and Bob starts the transaction simultaneously and withdraws &lt;em&gt;30$&lt;/em&gt; Bank account at the end is 100-(25+30) = &lt;em&gt;45$&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Math checks out.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1.d. Durability
&lt;/h2&gt;

&lt;p&gt;It states that if transaction has started and completed (&lt;code&gt;COMMIT&lt;/code&gt; is done); its effect should be persisted, even if there is a system failure. If there was a transaction that has not been completed, it should be rolled back to the previous completed state. It should be noted that databases commit first to Buffer Pool and then to disk. Durability is a guarantee at the disk level.&lt;br&gt;&lt;br&gt;
Similarly to Atomicity; Durability uses &lt;code&gt;REDO/UNDO&lt;/code&gt; or &lt;strong&gt;Shadow Paging&lt;/strong&gt; mechanism to ensure Durable state.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Are you durable, even when you are down and out?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  BASE
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lTh_M6Y0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249530139/5be0e449-c8ff-4340-9e6b-13641b1a0f7c.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lTh_M6Y0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249530139/5be0e449-c8ff-4340-9e6b-13641b1a0f7c.jpeg" alt="" width="400" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we go into BASE; we need to know the history of misnomers in database. BASE and NoSQL are really what they are intended to be. Just for sake of blog, I have added this section. This acronym (BASE) should be taken by grain of salt. This is marketing gimmick in order to hide the real important concepts such as CAP (and later PACLEC) and the OG ACID.&lt;/p&gt;

&lt;p&gt;Even the acronym is the mash of 3 things (Basic Availability, Soft state and Eventual Consistency) fitting into a 4 letter acronym and an alternative to ACID from the chemistry world.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.a. Basic Availability
&lt;/h2&gt;

&lt;p&gt;As NoSQL prioritises Scalability and Availability over transaction correctness; it needs to be available at all times with highest five 9s percentile (99.999).&lt;/p&gt;

&lt;h2&gt;
  
  
  2.b. Soft State
&lt;/h2&gt;

&lt;p&gt;This is related to eventual consistency. It basically is a disclaimer that the data available in the database is not the final state. Due to eventual consistency across various nodes; the data will not be guaranteed to be &lt;em&gt;write-consistent&lt;/em&gt; or &lt;em&gt;mutually consistent&lt;/em&gt; across nodes.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.c. Eventual Consistency
&lt;/h2&gt;

&lt;p&gt;As there are multiple machines in NoSQL databases due to various reasons such as sharding, horizontal scaling and goal is to be as fast as possible; data might be distributed across various nodes; and whichever node gives the answer first; is treated as the response to the API request. This means that data is consistent eventually across multiple machines. In the initial days, consensus was not the norm in NoSQL databases and hack ways to fan-out requests and pick the first one in order to be first was the norm. Consensus protocol such as Raft and Paxos where then integrated to have consistency (at the expense of performance.)&lt;/p&gt;

&lt;h1&gt;
  
  
  CAP
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2JtsmdGh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249570779/bfc0cf9b-f587-48e0-9ee8-2129ff306ccd.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2JtsmdGh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249570779/bfc0cf9b-f587-48e0-9ee8-2129ff306ccd.jpeg" alt="" width="386" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3.a. Consistency
&lt;/h2&gt;

&lt;p&gt;This is not to be confused with Consistency in ACID.&lt;/p&gt;

&lt;p&gt;C in ACID is meant for transaction as a series of steps inside the single node; whereas Consistency in CAP theorem considers a distributed environment where there are 2 or more machines/nodes. It resembles more of &lt;strong&gt;linearizability&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Formal definition of linearizability: If operation B started after operation A successfully completed, then operation B must see the the system in the same state as it was on completion of operation A, or a newer state.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zIUXnIXG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249583483/077ea9dd-8025-4bb0-be6a-2e57a3d34d95.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zIUXnIXG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249583483/077ea9dd-8025-4bb0-be6a-2e57a3d34d95.png" alt="" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the diagram, there are 5 steps which ensure data is distributed consistently.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Server A&lt;/em&gt; sets A's value as &lt;strong&gt;3&lt;/strong&gt; to the &lt;em&gt;primary database&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Primary database&lt;/em&gt; starts to propagate this info to the &lt;em&gt;Replica database&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;A=3&lt;/code&gt; travels across the network and reaches&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Primary database&lt;/em&gt; acknoledges that this info has be sent to &lt;em&gt;Replica database&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Server B&lt;/em&gt; reads from &lt;em&gt;Replica database&lt;/em&gt; and gets &lt;code&gt;A=3&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;if step #4 .i.e. Primary Acknowledging that transaction has been &lt;strong&gt;committed&lt;/strong&gt; , then the replicas would have consistent data immediately (No Eventual consistency)&lt;/p&gt;

&lt;p&gt;Consistency in CAP in simple terms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Alway return &lt;strong&gt;up-to-date&lt;/strong&gt; information&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3.b. Availability
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--diEWFfWV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249589564/846f1822-6dcb-4c83-a7d5-fa2aa9a7275a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--diEWFfWV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249589564/846f1822-6dcb-4c83-a7d5-fa2aa9a7275a.png" alt="" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consider that one of databases is down and consider the diagram:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Server A&lt;/em&gt; sets A's value as &lt;strong&gt;3&lt;/strong&gt; to the &lt;em&gt;primary database&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Primary database&lt;/em&gt; starts to propagate this info to the &lt;em&gt;Replica database&lt;/em&gt;; but finds that &lt;em&gt;Replcia database&lt;/em&gt; is down&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Server B&lt;/em&gt; reads from &lt;em&gt;Primary database&lt;/em&gt; and gets &lt;code&gt;A=3&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Availability in CAP in simple terms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;System &lt;strong&gt;must&lt;/strong&gt; return information, even if out-of-date/stale. Even if node goes down, there will be another node that brings information.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3.c. Partition Tolerance
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--leCTqfSC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249602401/bad3d541-b9b0-4473-9abc-7434c9288bc2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--leCTqfSC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249602401/bad3d541-b9b0-4473-9abc-7434c9288bc2.png" alt="" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the diagram above; the network is down. In this case Server A and Server B are on their own. So what do they do? They read from their own databases. &lt;em&gt;Server B's&lt;/em&gt; database thinks of itself as the primary database and it cannot connect to the primary database to get the latest info. When the network is established, the database have a reconciliation process wherein the data is brought to a "consistent". Note the asterisks; the consistent can become messy. Some databases look into lamport clocks to figure to the last update. If things are even more messy, then the application code does some woodo magic to make the data consistent enough.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nnlfzKMd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249609356/26c5d9ca-03f8-4741-a816-dfaa9bcf42f2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nnlfzKMd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249609356/26c5d9ca-03f8-4741-a816-dfaa9bcf42f2.png" alt="" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Partition Network tolerance in CAP in simple terms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;System continue operating even if &lt;strong&gt;Network link has been severed&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;CAP theorem states that a distributed system can follow only 2 out of 3 acronyms. The trade-off is always there when you have more than a single database. All in all, there is no free lunch.&lt;/p&gt;

&lt;h3&gt;
  
  
  CA
&lt;/h3&gt;

&lt;p&gt;CA means that data is the latest COMMIT which meands there are no inconsistent data in the distributed data sources as a whole. Mostly relational databases follow this.&lt;/p&gt;

&lt;h3&gt;
  
  
  CP
&lt;/h3&gt;

&lt;p&gt;Theses systems will not always answer if they are not &lt;strong&gt;available&lt;/strong&gt;. But if they do, you can be sure that the answer is correct due to its &lt;strong&gt;consistency guarantees&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  AP
&lt;/h3&gt;

&lt;p&gt;These systems will always give an answer, even if it is not the latest. Social media sites in early days; in hope to be very highly available and requiring partition for different regions/campuses (like Facebook), had loads of bugs where site loaded but posts and comments would come and go.&lt;/p&gt;

&lt;p&gt;The following VEN diagram is the list of databases supporting CA, CP and AP schemes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ilhVOPt5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249617984/f8ba5a7a-0ea4-4e07-983e-c5c9712a9367.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ilhVOPt5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249617984/f8ba5a7a-0ea4-4e07-983e-c5c9712a9367.png" alt="" width="748" height="790"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Critique of CAP theorem
&lt;/h3&gt;

&lt;p&gt;In spite of bringing a way of trade-off analysis to distributed system, in real world, it is not sufficient model to understand tradeoffs. A lot of times, Partition tolerance is needed and not a optional thing in the age of Mult-node deployments and on-soil regulations. Other critique is the network failure as the only failure is a wrong assumption. Databases also suffers from Murphy;s law. Power outage, Disk corruption etc are not part of CAP but are real scenarios that need to be considered. Martin Klepmann has a good blog on the critique of the CAP theorem which can be found &lt;a href="https://martin.kleppmann.com/2015/05/11/please-stop-calling-databases-cp-or-ap.html"&gt;here&lt;/a&gt;. (Paper format with even more details are &lt;a href="https://arxiv.org/pdf/1509.05393.pdf"&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;h1&gt;
  
  
  PACLEC: A better CAP
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;A more nuanced framework for comparing NoSQL databases&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It stands for: Partition Tolerant Always Available Consistent Else, choose Latency Consistency&lt;/p&gt;

&lt;p&gt;And yes, it is an acronym with a &lt;code&gt;IF/ELSE&lt;/code&gt; statement.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If (P)artition; Then (A)vailability and (C)onsistency&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(E)lse; (L)atency and (C)onsistency&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--teiE_YUw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249666664/d3d4bf51-c111-4e31-8aca-b19a55eac6d9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--teiE_YUw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1705249666664/d3d4bf51-c111-4e31-8aca-b19a55eac6d9.png" alt="" width="782" height="634"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Let us consider the left-hand side. If partition is all good; then you follow CAP theoem; albeit the CP or AP rule only.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For the right-hand side, if network partition is down; then you have to make a tradeoff between Latency and Consistency. If you want your system to be fast then you have to sacrifice consistent data. Conversely, if you want your data to be consistent, then you have to wait because of internal consensus (RAFT, Paxos, whatever) of the correct data.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;| Database | P+A | P+C | E+L | E+C |&lt;br&gt;
| BigTable | | | | |&lt;br&gt;
| HBASE | | | | |&lt;br&gt;
| Mongo | | | | |&lt;br&gt;
| MySQL/Postgress (and other RDBMS) | | | | |&lt;br&gt;
| Cassandra | | | | |&lt;br&gt;
| Scylla (Cassandra fork) | | | | |&lt;br&gt;
| Google Spanner | | | | |&lt;br&gt;
| CockroachDB | | | | |&lt;/p&gt;

&lt;p&gt;Watch this video from Dr Daniel Abadi on PACLEC (author of the concept) from &lt;a href="https://youtu.be/vnXXFpySYVE"&gt;ScyllaDB channel&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Closing thoughts
&lt;/h1&gt;

&lt;p&gt;This is just the start of understanding the basic terms of databases. There are many more concepts such as Memory Management, Buffer Cache, DB data-structures, Query planning &amp;amp; Execution, 2PC &amp;amp; Quorum, MVCC, Columnar Storage, WAL &amp;amp; Journaling and much more which is greatly covered in these 2 courses&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;CMU 15-721: Advanced database systems: &lt;a href="https://www.youtube.com/watch?v=uikbtpVZS2s&amp;amp;list=PLSE8ODhjZXjaKScG3l0nuOiDTTqpfnWFf"&gt;Playlist&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CMU 445-645: Advanced database systems &lt;a href="https://www.youtube.com/watch?v=LWS8LEQAUVc&amp;amp;list=PLSE8ODhjZXjYzlLMbX3cR0sxWnRM7CLFn"&gt;Playlist&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>eBPF - Unleash the Linux kernel</title>
      <dc:creator>Ayman Patel</dc:creator>
      <pubDate>Sun, 07 Jan 2024 17:12:45 +0000</pubDate>
      <link>https://dev.to/aymanapatel/ebpf-unleash-the-linux-kernel-4jgf</link>
      <guid>https://dev.to/aymanapatel/ebpf-unleash-the-linux-kernel-4jgf</guid>
      <description>&lt;h2&gt;
  
  
  User Space vs Kernel Space
&lt;/h2&gt;

&lt;p&gt;In order to understand where eBPF comes into the picture, first we need to understand the basic difference of &lt;strong&gt;User Space vs Kernel Space&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AfgY_9kJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1704646362259/9fb24659-07df-4520-9152-bd2d9db04f68.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AfgY_9kJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1704646362259/9fb24659-07df-4520-9152-bd2d9db04f68.jpeg" alt="" width="800" height="650"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;eBPF fits into the kernel space; but giving a user-space analogy of the significance of eBPF to the Operating System would be what WASM was for the browser. WASM allowed applications to be written in non-javascript to be interpreted in the browser. It allowed products like Figma to be developed for the web. Sketch and Invision would not be able keep up with the power of Figma's powerful editor. Good news is that eBPF for its revolutionary and novel will aid in observing the kernel space and not bring any technologies on its knees.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why eBPF
&lt;/h2&gt;

&lt;p&gt;Say you want to look into what is happening inside the Linux; I mean really look into the nuts and bolts; you might use an interface from User Space that can talk to Kernel Space which would give information such as &lt;code&gt;File IO&lt;/code&gt;, &lt;code&gt;Network Traces&lt;/code&gt; etc. but this would cause 2 issues&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Any unexpected crash at the Kernel Space level can lead to lack of observability on root cause of failure&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As it is an interface, the hardware or other Kernel Level details could not be visible from User Space&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is where eBPF comes in and shines. It is a sort of Virtual Machine that hooks up inside the Kernel which allows visibility to the User Space from the Kernel. This opens up the pandora's box of possibilities of logging, instrumentation and security applications that could leverage eBPF.&lt;/p&gt;

&lt;h2&gt;
  
  
  History of BPF and eBPF
&lt;/h2&gt;

&lt;p&gt;eBPF's name has been derived from a old technology called as BPF (Berkely Packet Filter).&lt;/p&gt;

&lt;h3&gt;
  
  
  BPF
&lt;/h3&gt;

&lt;p&gt;BPF was first conceived in early 1990s (before Linux became mainstream) as a way to intercept network traffic from the kernel itself instead of relying on user-level processes. It was a &lt;strong&gt;network tap&lt;/strong&gt; (monitor network traffic) and &lt;strong&gt;packet filter&lt;/strong&gt; (filtering out unwanted packets to reduce noise in netowrk monitoring)&lt;/p&gt;

&lt;h3&gt;
  
  
  eBPF
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Video Recommendation : &lt;a href="https://www.youtube.com/watch?v=Wb_vD3XZYOA"&gt;eBPF: Unlocking the Kernel&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In early 2010s, there was a need for having better observability tools that could be defined in a software instead of hardware. Also, all the things that things that went from User Space to Kernel Space could crash unexpectedly without actually knowing what caused the crash at the Kernel space layer. Alexie wanted something that an application at User Space could call which would be a hook/probe-point to the Kernel which would further make a decision to send information to the User space. This is where eBPF was born.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6ZWgBuJ4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1704646430951/f5ba72ff-7a6d-4875-92bc-01178e8b9ed3.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6ZWgBuJ4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1704646430951/f5ba72ff-7a6d-4875-92bc-01178e8b9ed3.jpeg" alt="" width="800" height="832"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  eBPF Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Us346NaY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1704646644895/1aff28db-90d4-419f-a21c-d3921f97337d.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Us346NaY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1704646644895/1aff28db-90d4-419f-a21c-d3921f97337d.jpeg" alt="" width="800" height="853"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;eBPF programs are called by hooks/probes either by Kernel or the user-land application. These hooks are pre-defined are include&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;System calls&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Function entry/exit: Custom Programs can attach to entry/exit functions so that they can run at these scenarios.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Kernel Tracepoints: Tracepoints are lightweight hooks to call a function at runtime. It is used for tracing and perf analysis at the kernel.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Network interfaces via XDP: eXpress Data Path (XDP) allows custom programs to attach to eBPF which can execute these custom program when the network packets are received.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LSI Module interface etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the hook/probe are not available for particular use-case; it is possible to attach probes to eBPF at both user and kernel levels. These are called &lt;code&gt;uprobe&lt;/code&gt; and &lt;code&gt;kprobe&lt;/code&gt; respectively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Loading
&lt;/h3&gt;

&lt;p&gt;Before a BPF can be run on the kernel; it requires to be &lt;strong&gt;Loaded&lt;/strong&gt; with the help of some eBPF loader libraries:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/cilium/ebpf"&gt;eBPF by Cilium&lt;/a&gt;: Go-based eBPF loading library&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/libbpf/libbpf"&gt;libbpf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Verification
&lt;/h3&gt;

&lt;p&gt;Need to ensure that the eBPF program is safe to run It make sure that it follows various conditions such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Program is run by priveleged eBPF program (unless stated otherwise)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Program does not bring the system down&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Program &lt;strong&gt;always run to completion&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  JIT Compilation
&lt;/h3&gt;

&lt;p&gt;Translating the eBPF bytecode (generated at &lt;strong&gt;User Space&lt;/strong&gt; ) into machine-readable code.&lt;/p&gt;

&lt;h3&gt;
  
  
  eBPF Maps
&lt;/h3&gt;

&lt;p&gt;These are required to hold and retrieve data. These hold wide variety of data such as&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Hash Tables&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Arrays&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stack traces&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;etc...&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Helper calls
&lt;/h3&gt;

&lt;p&gt;eBPF do not call kernel functions directly in order to make eBPF loosely couple with Kernel versions. eBPF call function calls to pre-defined helper functions defined by the kernel. These helper functions include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Current time and date&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Process/cgroup context&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Network packet manipulation and forwarding logic&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Random number generator&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Tail and Function Calls
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zlJ7XcHd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1704646469826/75b14211-f766-40aa-8be7-4d797f6843e6.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zlJ7XcHd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1704646469826/75b14211-f766-40aa-8be7-4d797f6843e6.jpeg" alt="" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;eBPF allows tail call of other eBPF functions which allows for compatibility and extendability of eBPF programs&lt;/p&gt;

&lt;h3&gt;
  
  
  Ensuring eBPF is safe
&lt;/h3&gt;

&lt;p&gt;As eBPF is a very powerful concept, which allows user-level programs to hook into kernel level details; it is imperative that the architecture of eBPF ensures that such a technology does not break the system when used.&lt;/p&gt;

&lt;h4&gt;
  
  
  Writing safe eBPF programs
&lt;/h4&gt;

&lt;p&gt;This includes&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;eBPF programs should be non-blocking. eBPF program can contain a loop if and only if, the &lt;strong&gt;Verifier&lt;/strong&gt; can ensure that loop exits!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;eBPF programs do not use out-of-bounds memory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;eBPF programs should be small&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;eBPF&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Hardening eBPF
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Kernel memory inside a eBPF program is read-only.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Spectre migration: Spectre was a big vulnerability in CPU architecture which allowed for out-of-order branch execution which lead to sensitive data access to attackers. eBPF prevents Spectre-type attacks at the &lt;strong&gt;Verifier&lt;/strong&gt; level&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Constant Binding&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  eBPF Applications
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6Hnmby-e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1704646528599/9ae9fe11-e9e6-45de-8d95-7c1b2b2bfc16.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6Hnmby-e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1704646528599/9ae9fe11-e9e6-45de-8d95-7c1b2b2bfc16.jpeg" alt="" width="800" height="1075"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Networking
&lt;/h2&gt;

&lt;p&gt;Networking use-cases for eBPF include doing &lt;strong&gt;Traffic Control&lt;/strong&gt; , controlling &lt;strong&gt;network policy&lt;/strong&gt; (via XDP) etc Tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.tigera.io/calico/latest/operations/ebpf/use-cases-ebpf"&gt;Calico Networking&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://cilium.io/use-cases/cni/"&gt;Cilium's CNI&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Observability
&lt;/h2&gt;

&lt;p&gt;Send Kernel Level details to observability platform&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/grafana/beyla"&gt;Grafana Beyla&lt;/a&gt; allows instrumentation of HTTP and HTTPS services from the Linux kernel to Grafana directly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/cilium/hubble/"&gt;Cilium's Hubble&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tracing
&lt;/h2&gt;

&lt;p&gt;Want to look into production tracing and troubleshooting. &lt;a href="https://github.com/iovisor/bpftrace"&gt;BPFTrace&lt;/a&gt; is the tool for you&lt;/p&gt;

&lt;p&gt;If wanted to know how the &lt;code&gt;VACUUM&lt;/code&gt; process is happening in Postgres under-the-hood. BPFTrace can help with that! Check this &lt;a href="https://github.com/iovisor/bpftrace"&gt;article to monitor Postgres's VACUUM process&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;List of eBPF based tracing tools&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/iovisor/bcc"&gt;BCC&lt;/a&gt; (Toolkit for creating kernel tracing tools)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/iovisor/bpftrace"&gt;BPFTrace&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Security
&lt;/h2&gt;

&lt;p&gt;Traditionally, &lt;a href="https://linux.die.net/man/8/auditd"&gt;auditd&lt;/a&gt; was used for auditing things happening in the Linux OS; but as it is user-space component; there is some performance penalty.&lt;/p&gt;

&lt;p&gt;Low-level observability through eBPF can aid in finding alerts for kernel level changes by attackers. For example, when application changes privileges are changed it can trigger an alert to a listening eBPF custom program&lt;/p&gt;

&lt;p&gt;Security Libraries that are based on eBPF&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://tetragon.io/"&gt;Tetragon&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kubearmor.com/"&gt;KubeArmour&lt;/a&gt;: K80based Security engine which used eBPF and Linux Security Modules (LSM)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Falco&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>The quest to improve Supply Chain Security</title>
      <dc:creator>Ayman Patel</dc:creator>
      <pubDate>Sun, 31 Dec 2023 03:30:10 +0000</pubDate>
      <link>https://dev.to/aymanapatel/the-quest-to-improve-supply-chain-security-37db</link>
      <guid>https://dev.to/aymanapatel/the-quest-to-improve-supply-chain-security-37db</guid>
      <description>&lt;h1&gt;
  
  
  Introduction with a sour taste
&lt;/h1&gt;

&lt;p&gt;Writing software is hard. Maintaining is harder. Securing it is the hardest. The attack vectors keep on increasing, year on year, as and when new features introduced. For instance, Log4j vulnerability that was seen a couple of years ago in December 2021, was because of a JNDI interface that was introduced in 2014. (&lt;a href="https://www.youtube.com/watch?v=Y8a5nB-vy78"&gt;Blackhat attack talk&lt;/a&gt; on the exploitability in 2016!) Another example would be that of &lt;strong&gt;Panama Papers leak&lt;/strong&gt; , where the open-source CMS Drupal was the &lt;a href="https://www.prometsource.com/blog/drupal-security-updates-and-panama-papers"&gt;root cause of the hack.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Third example which nails down is the &lt;strong&gt;Equifax&lt;/strong&gt; hack; whose root cause of not updating their Apache Struts vulnerability for &lt;a href="https://www.bleepingcomputer.com/news/security/equifax-confirms-hackers-used-apache-struts-vulnerability-to-breach-its-servers/"&gt;6 months&lt;/a&gt; after a 0-day exploit was found.&lt;/p&gt;

&lt;p&gt;Recent high-profile hacks which happened after the pandemic on Colonial pipelines, Microsoft Exchange server, Log4j, SolarWinds Hack; has made the people and governments weary of the security of software systems. Government has come up with legislation in order to curb these hacks.&lt;/p&gt;

&lt;h1&gt;
  
  
  Application Testing Tools
&lt;/h1&gt;

&lt;h2&gt;
  
  
  SAST
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Static Application Security Testing&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The security of application is determined by scanning static code. It does not have any information on the running application which can lead to some false-positives.&lt;/p&gt;

&lt;h2&gt;
  
  
  DAST
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Dynamic Application Security Testing&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The security of application is determined by running test on the running application. This can be achieved by sending malicious code/input fields . As it does not look into the code, it has not context on root cause of a security vulnerability. Hence, it will be difficult for developer to understand and guage what architectural/code issues are the root cause of the security vulnerability.&lt;/p&gt;

&lt;h2&gt;
  
  
  IAST
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Interactive Application Security Testing&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The security of application is determined by running an agent inside the application similar to agents deployed for monitoring such as Dynatace, eBPF etc It has advantages of both DAST and SAST. It can run against deployed application as well as see the source code.&lt;/p&gt;

&lt;p&gt;Following illustration is on what DAST, SAST, IAST tests:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U5zNEC92--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1703997703028/a2965239-b587-4ed8-bcda-f5d5d5746f5a.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U5zNEC92--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1703997703028/a2965239-b587-4ed8-bcda-f5d5d5746f5a.jpeg" alt="" width="800" height="871"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SCA
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Software Component Analysis&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This provides information on dependencies or libraries. Information include&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Downstream vulnerabilities&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;License risks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Library health (how well maintained is the library)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;SCA's provide an interface with dashboards on number of issues (license, vulnerability and package health); and also provide links to CVEs which can aid developers and security engineers to get all information of the software dependencies at a single place.&lt;/p&gt;

&lt;p&gt;| Type | Example | What | Cons | Pros |&lt;br&gt;
| SAST | Checkmax, Sonarqube | Look at code to find vulnerability | False positives possible | Find exact security issue in the client code |&lt;br&gt;
| IAST | Invicti, Semgrep, Contrast security | Interactive testing by embedded to running application and running security test against application | Requires agent to run which may not be available for a particular language | Ability to see source code like SAST while running real security attacks like DAST |&lt;br&gt;
| DAST | Bright security, Veracode DAST | Run security tests from outside | Developers cannot grt root cause of vulnerablity.Requires additional time root causing and fixing them. | Fast to run in CI/CD pipeline |&lt;br&gt;
| SCA | Synk, Blackduck | Look at vulnerabilities of libraries. Other things is also to consider licenses of libraries as well as how well-maintained | Very low Signal-to-noise ratio | Dashboard provides detals on security, package healt at one place |&lt;/p&gt;

&lt;p&gt;The following caability matrix by veracode provides the capabilities f each tool:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--daDJ_IXw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1703996759226/6b5ac010-30c2-448b-b13a-8d013fe48473.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--daDJ_IXw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1703996759226/6b5ac010-30c2-448b-b13a-8d013fe48473.jpeg" alt="" width="800" height="599"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  SBOM, VEX and CSAF
&lt;/h1&gt;

&lt;p&gt;According to US ruling, it is mandated for companies to include a software-bill-of-materials. Generally, bill of materials is traditionally a list of items that was used to build a particular product. For example, you might have heard of card recalls due to some fault at brake discs. BOM allows for auto-manufacturers to pinpoint the raw material to the cars where it was used, so that they can trace from raw materials to the cars where the materials were used. In software also, there are standards to define the components of software, which are mainly libraries.&lt;/p&gt;

&lt;p&gt;SCA might sound similar to SBOM; but goal of SBOM is to collaborate with other systems. SCA is vendor-specific, but SBOMs are driven by foundations such as OWASP and Linux Foundation, which provides interoperability for further things such as advisory framework, exploitability of vulnerability as well as signing of software packages to maintain authenticity of the packages.&lt;/p&gt;
&lt;h2&gt;
  
  
  SBOM
&lt;/h2&gt;

&lt;p&gt;There are 2 standards for SBOM&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;SPDX (by Linux foundation)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CylconeDX (by OWASP)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  SPDX
&lt;/h3&gt;

&lt;p&gt;This was created by Linux foundation in 2011 to track software licenses. After some years, information regarding the materials/components of software was added.&lt;/p&gt;
&lt;h3&gt;
  
  
  CycloneDX
&lt;/h3&gt;

&lt;p&gt;Cyclone DX was created by OWASP for combating vulnerability identification, outdate softwares and license compliance. It not only included SBOM but also &lt;a href="https://github.com/CycloneDX/bom-examples/blob/master/HBOM"&gt;HBOM&lt;/a&gt; (Hardware), &lt;a href="https://github.com/CycloneDX/bom-examples/blob/master/SBOM"&gt;OBOM&lt;/a&gt; (Operations), &lt;a href="https://github.com/CycloneDX/bom-examples/blob/master/SaaSBOM"&gt;SaaSBOM&lt;/a&gt; (Software as a Service), &lt;a href="https://github.com/CycloneDX/bom-examples/blob/master/VDR"&gt;VDR&lt;/a&gt; (Vulnerability Disclosure Report), &lt;a href="https://github.com/CycloneDX/bom-examples/blob/master/VEX"&gt;VEX&lt;/a&gt; (Vulnerability Explotability eXchange). VDR and VEX is more important and useful when used with SBOM for software engineers in order to find vulnerabilities, create a report on impact through advisory and finally making a decision if vulnerability is explitable in the current software stack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6elP01JY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cyclonedx.org/theme/assets/images/CycloneDX-Object-Model-Swimlane.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6elP01JY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cyclonedx.org/theme/assets/images/CycloneDX-Object-Model-Swimlane.svg" alt="CycloneDX Object Model Swimlane" width="800" height="660"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  SBOM Tools
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Anchore/Syft&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Generate SBOM for your container images, libraries, filesystems&lt;/p&gt;

&lt;p&gt;a. Generating CyclineDX and SPDX using &lt;a href="https://github.com/anchore/syft"&gt;Syft&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nC83H2dJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1703964005902/ef98829e-4c13-4a69-86d3-b0b613b13c29.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nC83H2dJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1703964005902/ef98829e-4c13-4a69-86d3-b0b613b13c29.jpeg" alt="" width="800" height="61"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;b. JSON output from SPDX and Cyclone DX&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ll76Eqgi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1703964009522/5d8e734e-be48-45a2-83cc-9445ade086ba.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ll76Eqgi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1703964009522/5d8e734e-be48-45a2-83cc-9445ade086ba.jpeg" alt="" width="800" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Anchore/Grype Works with Syft and does vulnerability scanning for containers as well as filesystems.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wvc8r6TF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1703964019222/75b7dc54-2ecb-49e2-99a2-fb9a64475ab5.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wvc8r6TF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1703964019222/75b7dc54-2ecb-49e2-99a2-fb9a64475ab5.jpeg" alt="" width="800" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0bkh0ztH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1703964022658/20ca64ea-14c9-473a-86de-3d47a0ffb977.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0bkh0ztH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1703964022658/20ca64ea-14c9-473a-86de-3d47a0ffb977.jpeg" alt="" width="800" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://snyk.io"&gt;Synk&lt;/a&gt; provides all tools under 1 hood. It provides tools such as&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Synk OpenSource: Identify vulnerable open source libraries&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Synk Container Image: Securing container images&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Snyk IaC: Misconfiguration of IaC secrets and policies&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Snyk Code: SAST offering form Snyk&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Aqua&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Aqua vSheild: Mitigation strategy for vulnerability&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Aqua Trivy: OSS Vulnerability scanner, IaC protection&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  VEX (Vulnerability eXploit)
&lt;/h2&gt;

&lt;p&gt;Goal of VEX is to provide information on the **to communicate the exploitability of components with known vulnerabilities in the context of the product in which they are used."&lt;/p&gt;

&lt;p&gt;Having a lot of libraries can lead to a lot of noise if there is a vulnerability. The vulnerability can be an obscure function which is hardly used. So in order to combat such scenarios, where we need clarity on the risk of the vulnerability so that appropriate action can be taken on fixing it or keeping it on hold for some time as it is not. arisk at this point of time.&lt;/p&gt;

&lt;p&gt;Goals of VEX:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;VEX can be inserted into a BOM (CycloneDX); or have an dedicated VEX BOM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide clear details on vulnerability, exploitability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bridge the communication gap between software consumer and software producer. It can communicate to software consumer on the actions taken by the software producer and actions to be taken by consumer to minimize security impact.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W9djYUqk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://aymanace2049.hashnode.dev/the-quest-to-improve-supply-chain-security" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W9djYUqk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://aymanace2049.hashnode.dev/the-quest-to-improve-supply-chain-security" alt="[E192622E-215F-445A-978B-4FBF76C1C020.jpeg]" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  CSAF
&lt;/h2&gt;

&lt;p&gt;Common Security Advisory Framework (CSAF) is a language to communicate security advisories. It is the final step of understanding the software components, and providing enough information in order to make the decision of remediating software vulnerabilities.&lt;/p&gt;

&lt;p&gt;It is maintained by OASIS Open and a CSAF v2.0 standard can be found &lt;a href="https://docs.oasis-open.org/csaf/csaf/v2.0/os/csaf-v2.0-os.html"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example CSAF JSON&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ "document": { "category": "csaf_vex", "csaf_version": "2.0", "notes": [{ "category": "summary", "text": "Example Company VEX document. Unofficial content for demonstration purposes only.", "title": "Author comment" }], "publisher": { "category": "vendor", "name": "Example Company ProductCERT", "namespace": "https://psirt.example.com" }, "title": "Example VEX Document Use Case 1 - Fixed", "tracking": { "current_release_date": "2022-03-03T11:00:00.000Z", "generator": { "date": "2022-03-03T11:00:00.000Z", "engine": { "name": "Secvisogram", "version": "1.11.0" } }, "id": "2022-EVD-UC-01-F-001", "initial_release_date": "2022-03-03T11:00:00.000Z", "revision_history": [{ "date": "2022-03-03T11:00:00.000Z", "number": "1", "summary": "Initial version." }], "status": "final", "version": "1" } }, "product_tree": { "branches": [{ "branches": [ { "branches": [ { "category": "product_version", "name": "1.1", "product": { "name": "Example Company DEF 1.1", "product_id": "CSAFPID-0001" } }], "category": "product_name", "name": "DEF" } ], "category": "vendor", "name": "Example Company" } ] }, "vulnerabilities": [{ "cve": "CVE-2021-44228", "notes": [ { "category": "description", "text": "Apache Log4j2 2.0-beta9 through 2.15.0 (excluding security releases 2.12.2, 2.12.3, and 2.3.1) JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled. From log4j 2.15.0, this behavior has been disabled by default. From version 2.16.0 (along with 2.12.2, 2.12.3, and 2.3.1), this functionality has been completely removed. Note that this vulnerability is specific to log4j-core and does not affect log4net, log4cxx, or other Apache Logging Services projects.", "title": "CVE description" }], "product_status": { "fixed": ["CSAFPID-0001"] } } ]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Signing your software libraries
&lt;/h1&gt;

&lt;p&gt;There are a couple of attack vectors that are based on how software is installed. A couple of years ago, security researcher wrote this article which went viral &lt;a href="https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610"&gt;"Dependency Confusion: How I Hacked Into Apple, Microsoft and Dozens of Other Companies"&lt;/a&gt;. He was able to download private repos from companies. Another example is series of attacks on npm where a misnomer(spelling mistake) of packages led to installation of malware. These sort of attacks could have been mitigated by using digital signatures.&lt;/p&gt;

&lt;p&gt;We have encryption which follows the practice of integrity, authenticity and non-repudiation. Software libraries signing can allow us to keep malicious packages out of our systems. There are a number of technologies which are using the signing principles of cryptography but for software binaries/libraries/containers signing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sigstore
&lt;/h2&gt;

&lt;p&gt;A standard and a collection of tools for enabling software components to be cryptographically digitally signed.&lt;/p&gt;

&lt;p&gt;It includes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Cosign: Signing software artifalcts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fulcio: Providing Certificate Authority&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rekor: Transparency log&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Gitsign: Signing Git commits&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenID integration: Authentication to check identity of requestor&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qj9bSlv3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.sigstore.dev/img/alt_landscapelayout_overview.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qj9bSlv3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.sigstore.dev/img/alt_landscapelayout_overview.svg" alt="Lifecycle of sigstore" width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Can see the demo of sigstore &lt;a href="https://www.youtube.com/watch?v=G7gU3WZTBpk"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Resources
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.cramhacks.com/p/INFINITE-CVES-WITH-SUPPLY-CHAIN"&gt;Infinite CVEs with Supply chain&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Semgrep&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ossf/wg-vulnerability-disclosures"&gt;OSSF Vulnerability disclosure&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Infrastructure as Code - A History Primer</title>
      <dc:creator>Ayman Patel</dc:creator>
      <pubDate>Sun, 17 Dec 2023 13:06:21 +0000</pubDate>
      <link>https://dev.to/aymanapatel/infrastructure-as-code-a-history-primer-5688</link>
      <guid>https://dev.to/aymanapatel/infrastructure-as-code-a-history-primer-5688</guid>
      <description>&lt;h1&gt;
  
  
  Phase 0: BASH
&lt;/h1&gt;

&lt;h4&gt;
  
  
  BASH
&lt;/h4&gt;

&lt;p&gt;In the early days, our configuration where written in BASH scripts. But the POSIX compliance nightmare meant that these BASH or Shell or Fish or whatever shell your OS is on became a nightmare to debug and extend. &lt;code&gt;!#/usr/bin/sh&lt;/code&gt; should have been the norm, but alas here we are trying to mitigate this disaster by creating an abstraction on top of OS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NStmg_rw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1702816587734/9414e5de-ca12-4157-9df3-98427e0b162d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NStmg_rw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1702816587734/9414e5de-ca12-4157-9df3-98427e0b162d.png" alt="Phase 1: 1990s and late 2000s; Phase 2: Mid to late 2010s" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Phase 1: CFEngine and the rest
&lt;/h1&gt;

&lt;p&gt;1990s brought in the abstraction of OS-based IaC tools. it started with &lt;a href="https://en.wikipedia.org/wiki/CFEngine"&gt;CFEngine&lt;/a&gt; as a side project by Mark Burgess (Post doctorate student) to automate the workstations at his university. This sparked configuration management tools such as &lt;a href="https://en.wikipedia.org/wiki/Progress_Chef"&gt;Chef&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Puppet_(software)"&gt;Puppet&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Ansible_(software)"&gt;Ansible&lt;/a&gt; etc. in the late 2000s to early 2010s The above just gives a timeline of when these were created. These were fantastic tools at the time, when people rented servers but not from the cloud giants such as AWS, Azure, (probably GCP) etc. When the clouds came in, there seemed to be a shift in IaC to have tools which&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Interacted with the cloud providers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No have a vendor-lockin&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is when tools such as Terraform came which provided an abstraction over the cloud providers.&lt;/p&gt;

&lt;p&gt;Before we go further, we need to understand the pure basics of IaC tools. Before the event we need to see what IaC tools are not. IaC tools are not:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Programming languages: Terraform has custom DSL, Chef has Ruby DSL, Ansible is YAML-based, and Puppet has its own IaC DSL called Puppet Code. So there is nothing common between them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Target systems: Chef/Puppet/Ansible are built to configure servers and not cloud configurations; while Terraform, Crossplane, Pulumi were built to provision cloud servers.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So what exactly is IaC's core value? It is creating a state machine with 2 states (Current and Target); and 2 interactions (Coverge and Compare).&lt;/p&gt;

&lt;p&gt;We also need to add schema constructs to see what the IaC needs, as well as some sort of type-checking on what values can be passed. We'll discuss other aspects such as this in the &lt;em&gt;Cue Section&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZYTnlV-k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1702815762157/0771c863-4ef5-4a1f-b17e-307fb95206ff.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZYTnlV-k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1702815762157/0771c863-4ef5-4a1f-b17e-307fb95206ff.png" alt="" width="800" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  IaaS, PaaS, FaaS
&lt;/h3&gt;

&lt;p&gt;Apart from the traditional cloud; there was also a burst of different runtimes in the 2010s. There was OpenShift, Cloud Foundry, Kubernetes, OpenStack. All these tools required a way to be configured in its way. Mostly there was a YAML was the go-to to describe the metadata for the infrastructure to be deployed&lt;/p&gt;

&lt;h2&gt;
  
  
  YAML enters the chat
&lt;/h2&gt;

&lt;p&gt;However due to issues with readability and lack of extendibility; there was a shift in the industry to create an abstraction that will also work in a multi-cloud environment. Whilst the first-age IaC tools (Chef, Ansible etc.) were great for creating server resources; they became a laggard in the scheme of cloud providers. The abstraction that seemed to work for most folks is YAML. Yes, YAML is far from perfect. Indentation issues are just the tip of the iceberg. Did you know of the &lt;a href="https://www.bram.us/2022/01/11/yaml-the-norway-problem"&gt;Norway problem&lt;/a&gt;?!&lt;/p&gt;

&lt;p&gt;Yeah, writing &lt;code&gt;NO&lt;/code&gt; can break the YAML parser.&lt;/p&gt;

&lt;p&gt;It is great for readability but a very nice way to "shoot into your foot by CTRL-C and CTRL-V". Not just IaC, but your environment variables, and &lt;code&gt;properties.yaml&lt;/code&gt; are also IaC code which are usually key-value pairs. If these are copy pasted without having any validation logic; then you will have a nice surprise waiting for you when you deploy your code to higher environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 2: Terraform and modern IaCs
&lt;/h2&gt;

&lt;p&gt;Terraform, Crossplane and Pulumi are great tools for writing IaC. But the issue it writing your &lt;strong&gt;adapter&lt;/strong&gt; for your custom &lt;strong&gt;Infrastructure&lt;/strong&gt; for your specific &lt;strong&gt;company&lt;/strong&gt; can be a blocker in incorporating tools.&lt;/p&gt;

&lt;p&gt;Pulumi is a programmatic IaC tool where you can write your IaC code in Javascript, Go etc&lt;/p&gt;

&lt;p&gt;Crossplane is a new way of writing IaC. It is not a simple CLI tool like Terraform. It is a control plane that always observes the infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  CUE: A guardrail to write custom configurations
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qHGJdbKi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cuelang.org/images/cue.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qHGJdbKi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cuelang.org/images/cue.svg" alt="CUE lang" width="338" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Any IaC, deployed anywhere needs some basic principles.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Schemas: Schemas are required to validate the structure of your config file. If you are deploying to Cloud Foundry; need to validate your &lt;code&gt;manifest.yml&lt;/code&gt; file, in K8s you configure your &lt;code&gt;kubectl&lt;/code&gt; file. All these tools bring the onus of correctness to the developer without providing any structured knowledge within the code on how to write these YAML configurations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Type-checking and constraints: Having a way to restrict the config value to a certain range of values is a very basic human error. A rule on incrementing the version for every release or not adding an absurdly high storage value to reduce costs are things etc.. should not be a checklist but a validation step during in order to commit the code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Overlays or Schema Import: Have a way to extend the schema (either externally via schema import or internally within the config file using overlays.)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Cue: History
&lt;/h2&gt;

&lt;p&gt;Cue was a project started by Marvel Lohuizen who worked primary at Borg (Kubernetes equivalient at Google) on the Borg Config Lang.&lt;/p&gt;

&lt;p&gt;Its goal is to provide a declarative approach to configuring things based on rules on those data. For example, you want to configure your IP address to a range of subnets only.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9H0bFKQK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1702817564453/ccc3981a-ccfa-4066-ba3e-0f862aeddf39.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9H0bFKQK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1702817564453/ccc3981a-ccfa-4066-ba3e-0f862aeddf39.png" alt="" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: Cue Vet
&lt;/h3&gt;

&lt;p&gt;Problem Statement: You want to make sure your S3 Buckets are deployed to an EU region only (for GDPR reasons) and you need to deploy to a specific folder &lt;code&gt;my-compliant-product-folder&lt;/code&gt; ; and you have a YAML which is custom to your infrastructure. What would you do?&lt;br&gt;&lt;br&gt;
Write BASH scripts? Too much headache and different OSes (macOS, Windows, Linux, Alpine, FreeBSD) will make this script fragile like a ice sheet.&lt;/p&gt;

&lt;p&gt;Write a python validator? Maybe, but that is time spent on creating a framework/DSL in which you are not an expert in.&lt;/p&gt;

&lt;p&gt;Enter Cue,&lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;bucketSchema.cue&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id: stringtype: "s3" | "minio"region: "es-east-2" | "eu-west-1"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your YAML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id: Rg98GoEHBd4type: s3region: us-east-2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your cue vet command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  cue vet bucketSchema.cue bucketPolicy.yaml region: 2 errors in empty disjunction:region: conflicting values "eu-east-2" and "us-east-2": ./bucketPolicy.yaml:4:9 ./bucketSchema.cue:6:9region: conflicting values "eu-west-1" and "us-east-2": ./bucketPolicy.yaml:4:9 ./bucketSchema.cue:6:23
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oh wait, you put a &lt;strong&gt;us&lt;/strong&gt; instead of an &lt;strong&gt;eu;&lt;/strong&gt; and you have deployed to US; hence making you non-compliant!&lt;/p&gt;

&lt;p&gt;Good thing we ran that vet command. We can fix it by changing our YAML config.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id: Rg98GoEHBd4type: s3region: eu-east-2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this and you can see no more errors. This simple construct can make us engineer not go into CtrlC-CtrlV mistakes&lt;/p&gt;

&lt;p&gt;For more info on Cue; I would suggest their doc and this video&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://cuelang.org/docs/usecases/"&gt;Documentation&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=fR_yApIf6jU&amp;amp;t=1619s"&gt;Youtube video&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Its many other use cases include&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Data Validation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Policy checking&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cross-language test generation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cue is able to export schema to OpenAPI definitions or even protobufs!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Marveling on Metrics &amp; Observibility with TSDB</title>
      <dc:creator>Ayman Patel</dc:creator>
      <pubDate>Sun, 03 Dec 2023 12:32:53 +0000</pubDate>
      <link>https://dev.to/aymanapatel/marveling-on-metrics-observibility-with-tsdb-276e</link>
      <guid>https://dev.to/aymanapatel/marveling-on-metrics-observibility-with-tsdb-276e</guid>
      <description>&lt;p&gt;Software engineers deal with 2 things. Code they write and metrics they monitor. Mostly we are ok or know what the code is and what it does. But from an observability point-of-view; we are winging it with our naive assumptions on the data that is emitted by our application. We don't even know how frequently our data is sampled, what a time-series database is, and what the querying engine used.&lt;/p&gt;

&lt;p&gt;We just dump data into these without considering what the data represents. We also do not consider what to query. Do I query the average inherently wrong response time?&lt;/p&gt;

&lt;h1&gt;
  
  
  Time Series 101
&lt;/h1&gt;

&lt;p&gt;So what is a time series anyway? Well from its &lt;a href="https://en.wikipedia.org/wiki/Time_series"&gt;Wikipedia definition&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A &lt;strong&gt;time series&lt;/strong&gt; is a series of &lt;a href="https://en.wikipedia.org/wiki/Data_point"&gt;data points&lt;/a&gt; indexed (or listed or graphed) in time order.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the software world, it is the collection of observable metrics that are taken at a defined regular internal.&lt;/p&gt;

&lt;p&gt;It is a kind of emitted event that has metadata info (usually added as Key-Value tags) with a timestamp&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--event_name-|--------[tagKey:tagValue]----------------- |-value-|---timestamp------|cpu_load_usage[location:us-east-one;application:web-sever]-&amp;gt;75%-&amp;gt;2023-02-02 00:00:00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Gotchas
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Gotcha 1: Average and Standard Deviation Suck!
&lt;/h3&gt;

&lt;p&gt;One thing we look at when we see a metric is average (and standard deviation). I have made the same mistake. Averages and standard deviation matter when they are part of normal distribution (which you see in statistics). However real-world metric data is anything but a normal distribution. Also, an outlier always skews your metric to either side, which is a different picture (either better-than-actual or worse-than-actual view for that metric).&lt;/p&gt;

&lt;p&gt;Helpful alternatives are median, 50 or above percentiles (Median is p50 anyway!).&lt;/p&gt;

&lt;p&gt;That is why it is imperative to use a TSDB. These gather various metrics in various formats while keeping in mind the need for aggregating and sampling of data which is required to gather the real-world picture of the software system that is deployed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gotcha 2: Cardinality is where $$$ is to be saved
&lt;/h3&gt;

&lt;p&gt;While you have a TSDB; it makes the development and product team inclined with an urge to custom tags/fields. Well, there ain't any free lunch in terms of storage cost and query execution time. Observability is both an art and science or which metric to measure. This &lt;a href="https://www.youtube.com/watch?v=EmZ6wycniGs"&gt;talk&lt;/a&gt; gives a good framework for selecting the metrics. Metrics should be moved to buckets of heavily used, moderately used and least used along with cardinality data. Removing less used metrics with high cardinality (more unique, dissimilar rows)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0zx8iCvW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1701605461434/c317d3ba-916c-4066-ae17-d463cf3af000.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0zx8iCvW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1701605461434/c317d3ba-916c-4066-ae17-d463cf3af000.png" alt="" width="605" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So let the person who owns the Monitoring tool sleep with peace!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Uba5r8bF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1701605088662/c5762ce2-8fe5-4ef0-bc78-fbb4d5fe5cda.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Uba5r8bF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1701605088662/c5762ce2-8fe5-4ef0-bc78-fbb4d5fe5cda.png" alt="" width="605" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Tools
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Graphite
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qcoKbqUW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://grafana.com/static/assets/img/v2/graphite.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qcoKbqUW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://grafana.com/static/assets/img/v2/graphite.png" alt="" width="800" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Carbon
&lt;/h3&gt;

&lt;p&gt;It is a &lt;a href="https://en.wikipedia.org/wiki/Daemon_(computing)"&gt;daemon(aka background process)&lt;/a&gt; for handling how time-series data is handled before sending it to Graphite's TSDB (Whisper or Ceres).&lt;/p&gt;

&lt;p&gt;There are 4 components of Carbon&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;

&lt;ol&gt;
&lt;li&gt;Carbon-relay&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Use for replication and sharding of the data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Grafana has its implementation of carbon-relay called &lt;a href="https://github.com/grafana/carbon-relay-ng"&gt;carbon-relay-ng&lt;/a&gt; which is blazingly fast, built-in aggregator functionality such as cross-series &amp;amp; cross-time aggregations .etc. Read more on the &lt;a href="https://grafana.com/docs/grafana-cloud/send-data/metrics/metrics-graphite/data-ingestion/"&gt;Grafana doc site&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;

&lt;ol&gt;
&lt;li&gt;Carbon-aggregator&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Used to aggregate metrics. Why aggregate? As too much data can lead to a lot of noise, performance degradation as well and storage costs; carbon-aggregator attempts to reduce the cardinality/granularity of data which ultimately leads to better I/O performance&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;

&lt;ol&gt;
&lt;li&gt;Carbon-cache&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It takes data coming from the &lt;strong&gt;carbon-aggregator&lt;/strong&gt; and dumps it to Whisper(or Ceres) for persistent storage. It also loads some of the data into RAM for faster access.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;

&lt;ol&gt;
&lt;li&gt;Carbon-aggregator-cache&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is a combination of both Carbon-cache and Carbon-aggregator in order to reduce the resource utilization of running both as separate daemons.&lt;/p&gt;

&lt;h3&gt;
  
  
  Database and Data Storage
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Whisper&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A fixed-size database which is similar to &lt;a href="https://joojscript.medium.com/what-you-know-about-round-robin-databases-e9a33c34277d"&gt;Round-Robin-database aka RRD&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unlike RDD, Whisper allows to backfill data which allows to import historical data. FOr more differences; &lt;a href="https://graphite.readthedocs.io/en/latest/whisper.html#differences-between-whisper-and-rrd"&gt;read the doc&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;StatsD&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is not a database per se, but it is commonly used as a data collector in Graphite to send additional information to the graphite instance. Information such as &lt;a href="https://github.com/statsd/statsd/blob/master/docs/metric_types.md#statsd-metric-types"&gt;Gauges, Counters, Timing Summary Statistics, and Sets&lt;/a&gt; can be sent to Graphite.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query language&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Graphite provides &lt;a href="https://graphite.readthedocs.io/en/latest/functions.html"&gt;&lt;strong&gt;functions&lt;/strong&gt;&lt;/a&gt; to query, manipulate, and transform data from the stored time series data.&lt;/p&gt;

&lt;p&gt;List of &lt;strong&gt;functions&lt;/strong&gt; (Exhaustive list &lt;a href="https://graphite.readthedocs.io/en/latest/functions.html#functions"&gt;here&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;| Function | What | Example |&lt;br&gt;
| absolute | Apply the mathematical absolute function | &lt;code&gt;absolute(Server.instance01.threads.busy)&lt;/code&gt; |&lt;br&gt;
| add | Add constant to the metric | &lt;code&gt;add(Server.instance01.threads.busy, 10)&lt;/code&gt; |&lt;br&gt;
| aggregate | Aggregate series using a given function (avg, sum, min, max, diff, stddev, count, range, last, multiply) | &lt;code&gt;aggregate(host.cpu-[0-7].cpu-{user,system}.value, "sum")&lt;/code&gt; |&lt;/p&gt;
&lt;h3&gt;
  
  
  Data Ingestion
&lt;/h3&gt;

&lt;p&gt;Graphite supports 3 data ingestion methods&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Plaintext&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pickle&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AMQP&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;| Method | Format | Usage | &lt;code&gt;carbon.conf&lt;/code&gt; &lt;a href="https://github.com/graphite-project/carbon/blob/master/conf/carbon.conf.example"&gt;Reference&lt;/a&gt; |&lt;br&gt;
| Plaintext | &lt;code&gt;&amp;lt;metric path&amp;gt; &amp;lt;metric value&amp;gt; &amp;lt;metric timestamp&amp;gt;&lt;/code&gt; | Quick and trivial monitoring | |&lt;br&gt;
| Pickle | &lt;code&gt;[(path, (timestamp, value)), ...]&lt;/code&gt; | Allows multi-levbel tuples | &lt;code&gt;DESTINATION_PROTOCOL&lt;/code&gt; and other &lt;code&gt;PICKLE_RECIEVER_*&lt;/code&gt; |&lt;br&gt;
| AMQP | | Reliable data transfer via AMQP broker. | &lt;code&gt;ENABLE_AMQP&lt;/code&gt; and other &lt;code&gt;AMQP_*&lt;/code&gt; configs |&lt;/p&gt;
&lt;h3&gt;
  
  
  Data Model
&lt;/h3&gt;

&lt;p&gt;There are 2 data formats for Graphite&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Simple Graphite message format&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Formatmetric_path value timestamp\n// Examplestats.api-server.tracks.post.500 -&amp;gt; 93 1455320690
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Graphite with Tag Support&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A lot of TSDB such as Influx, Prometheus had tag support from the beginning, hence Graphite added Tag support in v1.1 to identify different time series data&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Formatmy.series;tag1=value1;tag2=value2timestamp\n// Examplecpu,cpu=cpu-total,dc=us-east-1,host=tars usage_idle=98.09,usage_user=0.89 1455320660004257758=&amp;gt;cpu.usage_user;cpu=cpu-total;dc=us-east-1;host=tars 0.89 1455320690cpu.usage_idle;cpu=cpu-total;dc=us-east-1;host=tars 98.09 1455320690
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  InfluxDB
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x4GnUiKD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://c8.alamy.com/zooms/9/e6923294632c4ba09b246e959be26d08/2m7rdtd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x4GnUiKD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://c8.alamy.com/zooms/9/e6923294632c4ba09b246e959be26d08/2m7rdtd.jpg" alt="" width="640" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Database and Data Storage
&lt;/h3&gt;

&lt;p&gt;For the storage engine, InfluxDB uses TSM tree (similar to a Log-structured merge tree) for storage along with a Write Ahead Log. LSM is used in Cassandra and HBase which has good read/write characteristics. InfluxDB takes the database approach, while Prometheus data storage is mostly append append-only approach similar to Kafka.&lt;/p&gt;

&lt;p&gt;TODO: TSM explanation: &lt;a href="https://www.youtube.com/watch?v=J4syKnsqQmg"&gt;IPAD thingy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WAL(similar to Postgres) is a log for ensuring data reliability due to some unexpected failure to the InfluxDB server.&lt;/p&gt;

&lt;p&gt;Unlike Graphite and Prometheus which store on disk as a file, Influx DB stores data in their own relational-type storage engine which can be queried via InfluxDBQL or Flux(soon-to-be deprecated).&lt;/p&gt;

&lt;h3&gt;
  
  
  Query language
&lt;/h3&gt;

&lt;p&gt;There are 2 ways to query (one of them is being deprecated)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://docs.influxdata.com/influxdb/v2/query-data/influxql/"&gt;InfluxQL (SQL-like)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All InfluxDB functions can be &lt;a href="https://docs.influxdata.com/influxdb/v2/query-data/influxql/functions/"&gt;found here&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://docs.influxdata.com/influxdb/v1/flux/"&gt;Flux (In maintenance mode from InfluxDB v3)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   from(bucket:"telegraf/autogen") |&amp;gt; range(start:-1h) |&amp;gt; filter(fn:(r) =&amp;gt; r._measurement == "cpu" and r.cpu == "cpu-total" ) |&amp;gt; aggregateWindow(every: 1m, fn: mean)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Prometheus
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PBVoBwWo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:707/1%2ASW3lqH4V0J0suyzkZ6FcFQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PBVoBwWo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:707/1%2ASW3lqH4V0J0suyzkZ6FcFQ.png" alt="" width="707" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Database and Data Storage
&lt;/h3&gt;

&lt;p&gt;Unlike graphite originally, Prometheus stores in the following format with tags.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;api_server_http_requests_total{method="POST",handler="/tracks",status="500",instance="&amp;lt;sample1&amp;gt;"} -&amp;gt; 34api_server_http_requests_total{method="POST",handler="/tracks",status="500",instance="&amp;lt;sample2&amp;gt;"} -&amp;gt; 28api_server_http_requests_total{method="POST",handler="/tracks",status="500",instance="&amp;lt;sample3&amp;gt;"} -&amp;gt; 31
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prometheus stores its data in the following format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./data 01BKGV7JBM69T2G1BGBGM6KB12 meta.json 01BKGTZQ1SYQJTR4PB43C8PD98 chunks 000001 tombstones index meta.json 01BKGTZQ1HHWHV8FBJXW1Y3W0K meta.json 01BKGV7JC0RY8A6MACW02A2PJD chunks 000001 tombstones index meta.json chunks_head 000001 wal 000000002 checkpoint.00000001 00000000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Data is backed in a WAL (just like in InfluxDB). As it is an append-only log; it leads to compaction every 2 hours for saving space.&lt;/p&gt;

&lt;h3&gt;
  
  
  Query language
&lt;/h3&gt;

&lt;p&gt;PromptQL is similar to a functional approach (Like InfluxDB's Flux); with various functions for &lt;a href="https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors"&gt;selectors&lt;/a&gt;, &lt;a href="https://prometheus.io/docs/prometheus/latest/querying/functions/"&gt;functions&lt;/a&gt;, &lt;a href="https://prometheus.io/docs/prometheus/latest/querying/operators/"&gt;operators&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PromptQL can also be used inside &lt;a href="https://docs.influxdata.com/flux/v0/stdlib/internal/promql/"&gt;InfluxDB via Flux&lt;/a&gt;. But Flux not being supported in newer versions might lead to the risk of invalid PromptQL queries in the future.&lt;/p&gt;

&lt;h1&gt;
  
  
  Influx DB vs Prometheus
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Scaling
&lt;/h2&gt;

&lt;p&gt;As InfluxDB has a separate storage engine, it is horizontally scalable and decoupled from its storage engine (TSM). While Prometheus follows file-based data persistence, it is vertically scalable or via having a master Prometheus server that can pull data from Slave Prometheus servers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Push(Influx DB) vs Pull (Prometheus)
&lt;/h2&gt;

&lt;p&gt;Even though InfluxDB and Prometheus are useful tools in observing; their approach to gathering data is the opposite.&lt;/p&gt;

&lt;p&gt;InfluxDB uses a push model, wherein the source of data can be pushed to InfluxDB. Prometheus on the other hand uses a pull mechanism that can pull &lt;a href="https://prometheus.io/docs/instrumenting/exporters/"&gt;various sources&lt;/a&gt; including InfluxDB, Mongo, Postgres etc. InfluxDB can also pull from various sources; albeit not natively. You can use &lt;a href="https://www.influxdata.com/time-series-platform/telegraf/"&gt;Telegraf&lt;/a&gt; for this purpose.&lt;/p&gt;

&lt;p&gt;Use Prometheus when:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Want a powerful querying language&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;High Availability for uptime of your monitoring platform&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pulling from various sources natively.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Use InfluxDB when:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Scale horizontally with separate database nodes (given you are OK with the Eventual consistency that comes when you do horizontal scaling)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Long-term data storage&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;High cardinality(higher number of tags) requirement for metrics.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Prometheus is a very powerful tool, but it is neither here nor there. It is a great aggregation tool and should be looked at as a TSDB. A great resource on this though can be found &lt;a href="https://iximiuz.com/en/posts/prometheus-is-not-a-tsdb"&gt;here by Ivan Velichko&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>JSON - A rabbit hole of standards, implementations</title>
      <dc:creator>Ayman Patel</dc:creator>
      <pubDate>Sun, 08 Oct 2023 18:20:05 +0000</pubDate>
      <link>https://dev.to/aymanapatel/json-a-rabbit-hole-of-standards-implementations-4pdk</link>
      <guid>https://dev.to/aymanapatel/json-a-rabbit-hole-of-standards-implementations-4pdk</guid>
      <description>&lt;h1&gt;
  
  
  Why I got into this?
&lt;/h1&gt;

&lt;p&gt;When developing an application, we were implementing an API that had a number key type. Easy peasy lemon squeezy (🍋). But what we realized was that there was a really weird and frustrating bug. Apparently, the Javascript implementation of &lt;code&gt;JSON.stringify&lt;/code&gt; only works till 2^53 [&lt;a href="https://stackoverflow.com/a/34989371"&gt;Stackoverflow link&lt;/a&gt;], but we had to support for ~20 digits. The fix was to change it to string. We looked at the above link, made the fix and called it a day. Sidenote, Twitter also faced this issue 😅&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.twitter.com/en/docs/twitter-ids"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Iy9wiUo---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1696758759901/9e1f7cce-06c7-4cdd-aea6-530918ffd54b.png" alt="Twitter API Doc for showing JSON String shenanigans" width="800" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Classic case of Integer Overflow, right? But this is so weird, considering this is the 2020s era and not the 1970s where we are not bound by 16-bit (or even less) CPU architectures, with GBs (and not KBs) of RAM. That is when I dug into the rabbit hole of JSON. I found a lot of things that surprised me. From different JSON formats to different RFCs for JSON implementation itself to whatever the frontend (JS, looking at you) world brings onto the table to fix JSON issues.&lt;/p&gt;

&lt;h1&gt;
  
  
  JSON Implementations
&lt;/h1&gt;

&lt;p&gt;This is a web of implementations. A very apt blog is &lt;a href="https://seriot.ch/projects/parsing_json.html"&gt;JSON Parsing is a minefield&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;| RFC Number | Date | Status |&lt;br&gt;
| &lt;a href="https://datatracker.ietf.org/doc/html/rfc4627"&gt;RFC 4627&lt;/a&gt; | July 2006 | Obsoleted by &lt;a href="https://datatracker.ietf.org/doc/html/rfc7159"&gt;RFC 7159&lt;/a&gt;, &lt;a href="https://datatracker.ietf.org/doc/html/rfc7158"&gt;RFC 7158&lt;/a&gt; |&lt;br&gt;
| &lt;a href="https://datatracker.ietf.org/doc/html/rfc8259"&gt;RFC 8259&lt;/a&gt; | December 2017 | Internet Standard |&lt;br&gt;
| &lt;a href="https://datatracker.ietf.org/doc/html/rfc7159#section-6"&gt;RFC 7159&lt;/a&gt; | March 2014 | Proposed Standard |&lt;/p&gt;

&lt;p&gt;&lt;a href="https://datatracker.ietf.org/doc/html/rfc4627"&gt;RFC 4627&lt;/a&gt; can be looked at as a legacy RFC which has become obsoleted by #7159.&lt;/p&gt;

&lt;p&gt;The only difference between RFC 8259 and RFC 7159 is that &lt;a href="https://datatracker.ietf.org/doc/html/rfc8259#section-8.1"&gt;RFC 8259 has strict UTF-8 requirements&lt;/a&gt; while RFC 7159 can have UTF-16, UTF-32 in addition to UTF-8.&lt;/p&gt;

&lt;p&gt;My reaction:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VoivA0Gm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1696788999068/68eb33b6-db61-4a9d-9d32-1e8137d907e5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VoivA0Gm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1696788999068/68eb33b6-db61-4a9d-9d32-1e8137d907e5.png" alt="" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  JSON Formats
&lt;/h1&gt;

&lt;p&gt;Many formats augment JSON to create a kind of DSL.&lt;/p&gt;

&lt;p&gt;The most popular format is JWT (JSON Web Token, and the rest of the JSON Cryptographic suite). This is the most popular so we can skip that for now, as other blogs would explain this in great depth and clarity. There are some that we use in our daily lives but we just know them or some format that is present for niche use cases.&lt;/p&gt;

&lt;p&gt;This is the list I have come up with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;JSONSchema&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GEOJSON&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON-LD&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vega&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NDJSON&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HAR&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JWT&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'll go through the first two as I think these are more important to know as a software engineer.&lt;/p&gt;
&lt;h3&gt;
  
  
  JSON Schema
&lt;/h3&gt;

&lt;p&gt;When the world migrated from XML to JSON, the web was fine with making JSON "Schema-less". But as applications grew, we wanted to bring back schema so that there is some sanity with strong types/schema.&lt;/p&gt;

&lt;p&gt;JSON Schema is for that purpose only. Bring back the schemas!&lt;/p&gt;
&lt;h4&gt;
  
  
  Building Blocks
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VrIIsgzX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1696788163939/95d8e78b-e0ce-49a9-a8ac-3868b3e9bbd0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VrIIsgzX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1696788163939/95d8e78b-e0ce-49a9-a8ac-3868b3e9bbd0.png" alt="" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Schemas&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Allows to adhere to a specific schema. JSON Schema has various implementations such as Draft4, Draft5, Draft7&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Types&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Bring back the types!&lt;/p&gt;

&lt;p&gt;it can also encapsulate inside subschemas.&lt;/p&gt;

&lt;p&gt;List of types supported:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;string&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;number&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;array&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;boolean&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;nul&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Validations&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Rules on how JSON input can validate against the given schema. This can be of various types such as TypeValidations, Conditional, Regex Patterns etc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON Schema Example
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ // Can provide versions: draft-04, draft-05, draft-06, draft-07 "$schema": "http://json-schema.org/draft-04/schema#", "title": "User Profile", // Optional string for presenting to user "type": "object", // Validations "properties": { "userId": { "type": "integer", "description": "The unique identifier for a user" }, "firstName": { "type": "string", "description": "The user's first name" }, "lastName": { "type": "string", "description": "The user's last name" }, "email": { "type": "string", "format": "email", "description": "The user's email address" }, "phone": { "type": "string", "pattern": "^\\+?[0-9\\-\\s]+$", "description": "The user's phone number" }, "dateOfBirth": { "type": "string", "format": "date", "description": "The user's date of birth in YYYY-MM-DD format" } }, "required": ["userId", "firstName", "lastName", "email"]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Valid JSON Input
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ "userId": 12345, "firstName": "John", "lastName": "Doe", "email": "johndoe@example.com", "phone": "+123-456-7890", "dateOfBirth": "1990-01-01"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;NOTE: Can try out different JSONSchema Draft versions &lt;a href="https://www.jsonschemavalidator.net/"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ref&lt;/code&gt; can also be used for the recursive schema. Hence, you can achieve compatibility by following the DRY(Don't Repeat Yourself) principle&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example Schema:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Personnel Record", "type": "object", "properties": { "firstName": { "type": "string" }, "lastName": { "type": "string" }, "address": { "$ref": "#/definitions/address" } }, "required": ["firstName", "lastName", "address"], "definitions": { "address": { "type": "object", "properties": { "street": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" }, "postalCode": { "type": "string" } }, "required": ["street", "city", "state", "postalCode"] } }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Valid JSON Input
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ "firstName": "John", "lastName": "Doe", "address": { "street": "123 Main St", "city": "Springfield", "state": "IL", "postalCode": "12345" }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Usage
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Used for API validation. There are multiple parser libraries in different languages that can help&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Used in OpenAPI Swagger codegen specification to generate API validations for Swagger specifications&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON Validation for Mongo Collections (&lt;a href="https://www.mongodb.com/docs/manual/core/schema-validation/specify-json-schema/#std-label-schema-validation-json"&gt;Link&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  GeoJSON
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Wikipedia Link: &lt;a href="https://en.wikipedia.org/wiki/GeoJSON"&gt;https://en.wikipedia.org/wiki/GeoJSON&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;RFC Link: &lt;a href="https://datatracker.ietf.org/doc/html/rfc7946"&gt;https://datatracker.ietf.org/doc/html/rfc7946&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;GeoJSON data format is used in Geographical applications which could be geospatial or web mapping apps. It is based on JSON and contains geographical features such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Points&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Line Strings&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Polygons&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "properties": { "prop0": "value0" } }, { "type": "Feature", "geometry": { "type": "LineString", "coordinates": [[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0] ] }, "properties": { "prop0": "value0", "prop1": 0.0 } }, { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ] ] }, "properties": { "prop0": "value0", "prop1": { "this": "that" } } } ]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Database Support
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Mongo provides &lt;a href="https://www.mongodb.com/docs/manual/geospatial-queries/"&gt;query operations on geospatial data&lt;/a&gt; (stored as GeoJSON objects in collections). They also provide &lt;a href="https://www.mongodb.com/docs/manual/core/indexes/index-types/index-geospatial/#std-label-geospatial-index"&gt;GeoSpatial Index&lt;/a&gt; for better read performance,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PostGIS, which is an extension of Postgres for storing geographic data has a function to function to query the geometric data as GeoJSON collection. (&lt;a href="https://www.flother.is/til/postgis-geojson/"&gt;Reference&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Language Support
&lt;/h4&gt;

&lt;p&gt;| Language | Lib Link | Notes |&lt;br&gt;
| Golang | - &lt;a href="https://github.com/paulmach/go.geojson"&gt;https://github.com/paulmach/go.geojson&lt;/a&gt; | |&lt;br&gt;
| - &lt;a href="https://github.com/paulmach/orb"&gt;https://github.com/paulmach/orb&lt;/a&gt; | Library for parsing GeoJSOON and doing 2d geometric calculations respectively | |&lt;br&gt;
| Golang | &lt;a href="https://github.com/tidwall/geojson"&gt;https://github.com/tidwall/geojson&lt;/a&gt; | Used by &lt;a href="https://tile38.com/"&gt;tile38&lt;/a&gt; |&lt;br&gt;
| Python | &lt;a href="https://pypi.org/project/geojson/"&gt;https://pypi.org/project/geojson/&lt;/a&gt; | Python utilities for GeoJSON |&lt;br&gt;
| Java | &lt;a href="https://github.com/opendatalab-de/geojson-jackson"&gt;GeoJSON Jackson&lt;/a&gt; | Serialize and desrialize GeoJSON POJOs |&lt;br&gt;
| Javascript | &lt;a href="https://developers.arcgis.com/javascript/latest"&gt;ArcGIS API&lt;/a&gt; | ArcGIS API for creating web based interactive workflows |&lt;br&gt;
| C# | &lt;a href="https://github.com/GeoJSON-Net/GeoJSON.Net"&gt;https://github.com/GeoJSON-Net/GeoJSON.Net&lt;/a&gt; | GeoJSON types and deserialziers |&lt;/p&gt;

&lt;h1&gt;
  
  
  Frontend solutions
&lt;/h1&gt;

&lt;p&gt;Things in frontend world are always awkward and weird. Maybe the hacking ethos still lives here. Trying out stuff, making it work, and just deviating from the rest of the world.&lt;/p&gt;

&lt;p&gt;There are a couple of solutions (npm libraries) that help to solve some shortcomings of JSON&lt;/p&gt;

&lt;h2&gt;
  
  
  SuperJSON
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Drop-in replacement for&lt;/em&gt; &lt;code&gt;json.stringify&lt;/code&gt; and &lt;code&gt;json.parse&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Created by &lt;a href="https://github.com/blitz-js/blitz"&gt;Blitz.js&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Safely serialize/deserialize unsupported JSON types like Date, BigInts, Map, Set, URL, and Regular Expressions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support Date and other Serialization for &lt;code&gt;getServerSideProps&lt;/code&gt; and &lt;code&gt;getInitialProps&lt;/code&gt; in Next.js&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://replit.com/@AymanArif1/Javascript-JSON-Enhancers#SuperJSONExample.js"&gt;https://replit.com/@AymanArif1/Javascript-JSON-Enhancers#SuperJSONExample.js&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Big Number Issue
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Default JSON&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Default Javascript implementation of &lt;code&gt;json.stringify&lt;/code&gt; cannot parse more than 2^53-bit characters&lt;/p&gt;

&lt;p&gt;We get an exception when trying to parse this. (Can check Replit's CLI)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WGzJOvkZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1696786676496/94ad87c9-4709-42b2-91f8-90b930e96524.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WGzJOvkZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1696786676496/94ad87c9-4709-42b2-91f8-90b930e96524.png" alt="" width="601" height="58"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SuperJSON&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Users
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;tRPC: Data transformer when creating proxy client (&lt;a href="https://trpc.io/docs/server/data-transformers"&gt;Link&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Blitz.js (Superjson's creator)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  JSON5
&lt;/h2&gt;

&lt;p&gt;JSON5&lt;/p&gt;

&lt;p&gt;Provides features such as JSON comments. In the frontend world, JSON is normally used for configuration purposes. The most common is the use of &lt;code&gt;package.json&lt;/code&gt;. Unlike all the different languages where the corresponding configuration has comment support, Node.js creator regretfully (after the fact) introduced &lt;code&gt;package.json&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Other features of JSON5 include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Allowing single-quoted string&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Strings that can span multiple lines&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Broader number support which includes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Users
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Babel&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next.js&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apple&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bun&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;This is a bit too much. I think part 2 would be required.&lt;/p&gt;

&lt;p&gt;I haven't touched JWT, JSON-LD (RDF), NDJSON, Vega, Avro. 1 thing is for sure, things are never-ending rabbit hole that requires digging till the end of time.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Client Hello - Security all the way down</title>
      <dc:creator>Ayman Patel</dc:creator>
      <pubDate>Sun, 01 Oct 2023 13:41:23 +0000</pubDate>
      <link>https://dev.to/aymanapatel/client-hello-security-all-the-way-down-48eo</link>
      <guid>https://dev.to/aymanapatel/client-hello-security-all-the-way-down-48eo</guid>
      <description>&lt;p&gt;Cloudflare has been working on a standard to encrypt the TLS connection at all levels. We will dig as to what stuff is still unencrypted, how this poses the threat and the solution &lt;strong&gt;ClientHello&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requisites
&lt;/h2&gt;

&lt;p&gt;Before diving into the protocol, it is imperative to understand the historical context of this protocol&lt;/p&gt;

&lt;p&gt;Existing TLS implementations contain a couple of parameters/extensions that are sent unencrypted and are used before the handshaking process. These are Server Name Identification(SNI) and Application-Layer Protocol Negotiation (ALPN)&lt;/p&gt;

&lt;p&gt;While establishing a TLS connection between client and server, these parameters (SNI and ALPN) are not encrypted. It is after these 2 params are exchanged, that the client and server have enough security information (certificates, cryptographic keys .etc.) to initiate a Secure Connection&lt;/p&gt;

&lt;h3&gt;
  
  
  SNI
&lt;/h3&gt;

&lt;p&gt;So what is SNI?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It is sent by the client indicating which hostname it wants to connect to before starting the TCP handshaking process&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Since the ISPs can see which hostname the client wants to connect,it allows them to block websites easily.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ALPN
&lt;/h3&gt;

&lt;p&gt;This provides information on what application-level protocol (HTTP version) should be used once the TLS connection has been established.&lt;/p&gt;

&lt;p&gt;Having unencrypted ALPN is an attack vector that can be used to downgrade HTTP version and thus negate all security improvements for every HTTP version upgrade.&lt;/p&gt;

&lt;p&gt;Since SNI and ALPN are considered metadata and can contain some sensitive information that is unencrypted, there has been a push to make this also encrypted. But this poses a chicken and egg problem, which is how can the client and server exchange encryption key before the handshaking process when the handshaking process itself is used for the same purpose?&lt;/p&gt;

&lt;p&gt;This concept of encrypting before handshake was not considered in earlier TLS versions. But after the Snowden leak and the uproar on global surveillance with only using metadata information, IETF started considering ways to encrypt this information as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  TLS Prerequisite
&lt;/h2&gt;

&lt;p&gt;A prerequisite for any TLS connection is the TCP handshake. As it is a topic in itself, you can view it &lt;a href="https://www.cloudflare.com/en-in/learning/ssl/what-happens-in-a-tls-handshake/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. In simple terms, it does these things&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Acknowledge both parties participating in TLS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Very each other&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Establish cryptographic algorithms they will use to securely connect and exchange information with each other.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Specify which TLS version to use (depending on what is supported by each party)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Authenticate server via Servers public key and CAs signature&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Basic TLS
&lt;/h2&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%2Ff4m152ypyjcjj2icp7e2.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%2Ff4m152ypyjcjj2icp7e2.png" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above is the initial SYN/ACK between client and server&lt;/p&gt;

&lt;p&gt;After that, there is a ClientHello and ServerHello (refer to the below diagram)&lt;/p&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%2F2mxe1msqutsyidy3xxzd.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%2F2mxe1msqutsyidy3xxzd.png" width="800" height="671"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ClientHello:&lt;/strong&gt; Cipher Suite, TLS version client supports, client random, SNI and ALN info&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ServerHello&lt;/strong&gt; : Servers Sl certificate (with CA who issued it), servers cipher suite, server random&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The rest of the steps can be viewed in the Cloudflare blog.&lt;/p&gt;

&lt;p&gt;Existing TLS implementations contain a couple of parameters/extensions that are sent unencrypted and are used before the handshaking process. These are Server Name Identification(SNI) and Application-Layer Protocol Negotiation (ALPN)&lt;/p&gt;

&lt;p&gt;It is after these 2 params are exchanged, that the client and server have enough security information (certificates, cryptographic keys etc.) to initiate a Secure Connection&lt;/p&gt;

&lt;h3&gt;
  
  
  SNI
&lt;/h3&gt;

&lt;p&gt;So what is SNI?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It is sent by the client indicating which hostname it wants to connect to before starting the TCP handshaking process&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Since the ISPs can see which hostname the server wants to connect, it allows them to block websites easily.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ALPN
&lt;/h3&gt;

&lt;p&gt;This provides information on what application-level protocol (HTTP version) should be used once the TLS connection has been established.&lt;/p&gt;

&lt;p&gt;Having unencrypted ALPN is an attack vector that can be used to downgrade HTTP version and thus negate all security improvements for every HTTP version upgrade.&lt;/p&gt;

&lt;p&gt;Since SNI and ALPN are considered metadata and can contain some sensitive information that is unencrypted, there has been a push to make this also encrypted. But this poses a chicken and egg problem, how can the client and server exchange the encryption key before the handshaking process when the handshaking process itself is used for the same purpose?&lt;/p&gt;

&lt;p&gt;This concept of encrypting before handshake was not considered in earlier TLS versions. But after the Snowden leak and the uproar on global surveillance with only using metadata information, IETF started considering ways to encrypt this information as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  ESNI
&lt;/h2&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%2F0aulc9a2ey9k13aa8s65.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%2F0aulc9a2ey9k13aa8s65.png" width="800" height="730"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ESNI was the first version of encrypting SNI. It evolved to what we have today which is &lt;strong&gt;ClientHello&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ESNI issues
&lt;/h3&gt;

&lt;p&gt;For key distribution, ESNI used DNS. And this keyboard distribution plain-text base-64 encoded for the ESNI Public key which would raise serious flags.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dig _esni.crypto.dance TXT +short"/wGuNThxACQAHQAgXzyda0XSJRQWzDG7lk/r01r1ZQy+MdNxKg/mAqSnt0EAAhMBAQQAAAAAX67XsAAAAABftsCwAAA="
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This negates the whole security aspect of SNT as plain-text DNS is easily traceable by ISP. One innovation that helped mitigate this was DNS-over-HTTPS (DoH).&lt;/p&gt;

&lt;h1&gt;
  
  
  Final puzzle Piece: ECH
&lt;/h1&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%2F8mv6pmv0i3cxy1jjgd43.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%2F8mv6pmv0i3cxy1jjgd43.png" width="800" height="730"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What ECH as the final draft proposes is to divide &lt;strong&gt;ClientHello,&lt;/strong&gt; into 2 parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ClientHelloOuter:&lt;/strong&gt; This contains information that is not sensitive such as what cipher suite is used, TLS version and &lt;strong&gt;outer SNI.&lt;/strong&gt; This outer-SNI can show CDN-type hostnames which would be common for most sites using CDN for improving edge performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ClientHelloInner:&lt;/strong&gt; This would include inner-SNI which would have an actual server name. This would be encrypted by a public key provided by Cloudflare. This could mean Cloudflare to be a point of vulnerability as they can decrypt by the private key that they possess.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ECH uses Hybrid Public Key Encryption (HPKE) for exchanging keys.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference: C Structs used in ECH
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;opaque HpkePublicKey;uint16 HpkeKemId; // Defined in &amp;lt;https://www.ietf.org/archive/id/draft-irtf-cfrg-hpke-05.txt&amp;gt;uint16 HpkeKdfId; // Defined in &amp;lt;https://www.ietf.org/archive/id/draft-irtf-cfrg-hpke-05.txt&amp;gt;uint16 HpkeAeadId; // Defined in &amp;lt;https://www.ietf.org/archive/id/draft-irtf-cfrg-hpke-05.txt&amp;gt;struct { HpkeKdfId kdf_id; HpkeAeadId aead_id;} ECHCipherSuite;struct { opaque public_name; // Entity trusted to update encryption keys HpkePublicKey public_key; // Public key to encrypt `ClientHelloInner` HpkeKemId kem_id; // Identifying public key ECHCipherSuite cipher_suites; // Cipher suite for encrypting `ClientHelloInner` uint16 maximum_name_length; Extension extensions; // } ECHConfigContents;struct { uint16 version; // Version of ECH for which this config is used uint16 length; // Length of next field (in bytes) select (ECHConfig.version) { // ECHConfigContents string case 0xfe08: ECHConfigContents contents; } } ECHConfig;ECHConfig ECHConfigs;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  ECH in the real world
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Setting up a flag in your browser
&lt;/h2&gt;

&lt;p&gt;Check if your browser has ECH enabled using this &lt;a href="https://defo.ie/ech-check.php" rel="noopener noreferrer"&gt;link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(Chrome, can be achieved by enabling &lt;code&gt;chrome://flags&lt;/code&gt; under &lt;code&gt;encrypted-client-hello&lt;/code&gt;)&lt;/p&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%2F85k5q0rwfprdqivbnwrw.jpeg" 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%2F85k5q0rwfprdqivbnwrw.jpeg" width="800" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Before enabling ECH&lt;/li&gt;
&lt;/ul&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%2Fno98fq685zzq1q1pcwwg.jpeg" 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%2Fno98fq685zzq1q1pcwwg.jpeg" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After enabling ECH&lt;/li&gt;
&lt;/ul&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%2F0qokdbs3h74n9ple763c.jpeg" 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%2F0qokdbs3h74n9ple763c.jpeg" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  No free lunch
&lt;/h1&gt;

&lt;p&gt;Well this helps with securing exchanging metadata before TLS handshake, there are still some concerns/flaws:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Issues for corporate networks to implement firewall rules&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenSSL open issue for 5 years &lt;a href="https://github.com/openssl/openssl/issues/7482" rel="noopener noreferrer"&gt;Github Link&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is still not an official RFC number attached (despite Google bringing this to the browser and Cloudflare releasing their &lt;a href="https://blog.cloudflare.com/announcing-encrypted-client-hello/" rel="noopener noreferrer"&gt;last puzzle piece to the privacy link&lt;/a&gt;.)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;RFCs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cloudflare blogs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;YouTube talks&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
