<?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: Christian Herlein</title>
    <description>The latest articles on DEV Community by Christian Herlein (@chrisherlein).</description>
    <link>https://dev.to/chrisherlein</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%2F619955%2F7a1220cd-18a0-4c28-b404-0ef17c4a99b4.jpeg</url>
      <title>DEV Community: Christian Herlein</title>
      <link>https://dev.to/chrisherlein</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chrisherlein"/>
    <language>en</language>
    <item>
      <title>Graphs are not data structures</title>
      <dc:creator>Christian Herlein</dc:creator>
      <pubDate>Mon, 17 Mar 2025 18:46:18 +0000</pubDate>
      <link>https://dev.to/cloudx/graphs-are-not-data-structures-m0f</link>
      <guid>https://dev.to/cloudx/graphs-are-not-data-structures-m0f</guid>
      <description>&lt;p&gt;In a programmer's lifetime, you have to deal with thousands of structures. In other words, you are always deciding how to organize your data. There are many options out there, from single variables to complex matrices of custom-defined structs. One of those common approaches is graphs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But graphs are not data structures: they are mathematical structures.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Of course, you can apply them as data structures; so many pieces of software depend on them. Even if you don't realize it, you are dealing with graphs all the time. For example, a linked list is just a special case of a directed graph.&lt;/p&gt;

&lt;p&gt;But when considering graphs as mathematical constructs rather than mere data structures, they become a much more powerful tool. Here I present two more applications of graphs in software development: as a processing design and as codebase representation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Although this is a general programming post, I'm using Go for the code examples.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Process by graphs
&lt;/h2&gt;

&lt;p&gt;Let's deal with this problem:&lt;/p&gt;

&lt;p&gt;We have to process each day's minimum temperature of a city (X), doing x³ and then the result square root or its opposite natural logarithm. Then, store the result into a map, using the result as the key and its certificate as the value.&lt;/p&gt;

&lt;p&gt;But we have to take care of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Numbers are 8-bit signed integers &lt;a href="https://dev.toGo:%20int8"&gt;-128; 127&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Handling real-number groups&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;x &amp;lt; 0&lt;/code&gt;, doing &lt;code&gt;sqrt(x³)&lt;/code&gt; will result in a math error. In such cases, the program will use &lt;code&gt;logn(-x)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;x³&lt;/code&gt; overflows &lt;code&gt;int8&lt;/code&gt; max value, will look for &lt;code&gt;logn(-x³)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;When looking for logn, we will ask a remote service for an error signature&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Is it a realistic problem? Of course not. But the abstract idea is present here.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Lets think in a traditional approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;  &lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;certs&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;
      &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;needCert&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;
      &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cert&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"no_need"&lt;/span&gt;

      &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="c"&gt;// testing for overflow scenarios&lt;/span&gt;
          &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
          &lt;span class="c"&gt;// we want the same behavior as x &amp;lt; 0&lt;/span&gt;
          &lt;span class="c"&gt;// Note: In Go, fallthrough transfers control to the&lt;/span&gt;
          &lt;span class="c"&gt;// next case rather than breaking out of the switch&lt;/span&gt;
          &lt;span class="k"&gt;fallthrough&lt;/span&gt; 
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;needCert&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
          &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
          &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;needCert&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;cert&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;askCert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="n"&gt;certs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cert&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we have problems: we are processing inputs one by one, we are trying to do all in the same place, processing in batch, and waiting for &lt;code&gt;askCert(x)&lt;/code&gt; response before processing another input. In summary, we are not being efficient and not applying clean code good practices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So, for cleaning this mess, we can take a different approach: graphs.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's assume we treat processes as vertices and communications as edges. Each process will perform one of our atomic operations: &lt;code&gt;x³&lt;/code&gt;, &lt;code&gt;x &amp;lt; 0&lt;/code&gt;, &lt;code&gt;sqrt(x)&lt;/code&gt; and &lt;code&gt;log(x)&lt;/code&gt;, and communication will be done via channels.&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%2F0mogvz06bjvjoljvof0r.jpg" 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%2F0mogvz06bjvjoljvof0r.jpg" alt="Illustration of a process graph showing how functions (nodes) communicate via channels (edges)." width="526" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To implement this, let's create each function assuming that it will run indefinitely (as nodes). Then, we pass them the input and output channels (edges). The clearest approach to declaring edges is to first define an adjacency matrix, then specify the corresponding channel types, and finally, assign edge weights (e.g., using buffer sizes in Go). Of course, doing this way is not strictly necessary; in the example of the full implementation below I'm declaring each channel manually, expecting to be clearer in the intentions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://go.dev/play/p/K4tpZ-flF5a" rel="noopener noreferrer"&gt;Playground code implementation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But, why would we want to create this mess? Two main factors: control and performance. That is because our example is just a base to start thinking. Processes are as flexible as we can imagine. One of the most important scenarios to apply is when you have a lot of I/O operations; you can use a vertex process to start background calls to your I/O operation and send its response to some other vertex where you know it will be used. That would reduce the awaiting time without compromising the remote resource, by avoiding an overload of calls (&lt;em&gt;an abstraction of "just in time" inventory system&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Cloud(x)&lt;/strong&gt; we applied this approach to enhance our customer's data processing—achieving a 16x improvement in combined time efficiency and resource utilization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code as Graph
&lt;/h2&gt;

&lt;p&gt;Another benefit is that it aids in the study and maintenance of software. You can apply graph theory to understand your codebase and even predict its behavior before writing any code.&lt;/p&gt;

&lt;p&gt;Studying code by itself is something that, as programmers, we usually don't do. &lt;strong&gt;But we should.&lt;/strong&gt; That topic has been studied by &lt;code&gt;German Cárdenas&lt;/code&gt; in his publication "&lt;em&gt;Evaluating the Graph-based Visualization Technique: A Controlled Experiment&lt;/em&gt;".&lt;/p&gt;

&lt;p&gt;The application of graphs to study codebases is not a new idea. Back in 2002, &lt;code&gt;Eva Van Emden&lt;/code&gt; and &lt;code&gt;Leon Moonen&lt;/code&gt; published "&lt;em&gt;Java Quality Assurance by Detecting Code Smells&lt;/em&gt;". In that research, they represented "&lt;em&gt;entities&lt;/em&gt;" of the software using graphs: packages, classes, methods, etc.&lt;/p&gt;

&lt;p&gt;To have graphs at a design stage is relatively common, but how much time do we actually invest in studying and maintaining these graphs? In my experience, almost no one will ever update a graph that was created in the early stages of the project. Plus, the graph will serve merely as a visual reference rather than as an active development tool.&lt;/p&gt;

&lt;p&gt;Imagine a fully updated graph representing your RESTful API encompassing functions, calls, and models. We will be able to quickly realize the effort of a change. You can apply &lt;code&gt;Depth First Search&lt;/code&gt; or &lt;code&gt;Breadth First Search&lt;/code&gt; to find out how many parts of your code will be affected. Then, take your &lt;code&gt;Dominators Tree&lt;/code&gt; to evaluate the risks of your plan. And of course, if the graph becomes disconnected (&lt;em&gt;your connectivity is greater than 1&lt;/em&gt;), you will quickly notice you have dead code to deal with.&lt;/p&gt;

&lt;p&gt;Let's also assign weights to edges to represent the expected execution time of functions. This allows us to estimate an endpoint's response time using &lt;code&gt;Dijkstra's algorithm&lt;/code&gt;. We would be able to calculate how many resources we need to serve the expected number of concurrent users, and what parts of our software require more optimizations.&lt;/p&gt;

&lt;p&gt;This topic is as extensive as graph theory itself. There is a wealth of studies and documentation available. It is up to you, as a developer, to adopt this knowledge and apply it to your daily work.&lt;/p&gt;

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

&lt;p&gt;As software developers, we know that there are too many tools available. Almost every year, a new technology or update with amazing features is released in the market, and many expect us to remain up-to-date and adopt them as quickly as possible to stay at the forefront of the tech industry. Consequently, we are drifting further away from fundamental principles.&lt;/p&gt;

&lt;p&gt;Periodically discussing computer science fundamentals helps us rediscover valuable tools, tricks, and best practices. It reminds us that we should continuously reflect on our implementations, and study their behavior instead of merely reapplying the same formula repeatedly.&lt;/p&gt;

&lt;p&gt;This time, graphs have been put into discussion. Their advantages are huge. We should harness their full potential rather than using them merely to structure data. Remember:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Graphs are not data structures.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>graphs</category>
      <category>optimization</category>
      <category>documentation</category>
    </item>
    <item>
      <title>About Ethics</title>
      <dc:creator>Christian Herlein</dc:creator>
      <pubDate>Tue, 18 May 2021 04:57:43 +0000</pubDate>
      <link>https://dev.to/chrisherlein/about-ethics-1geh</link>
      <guid>https://dev.to/chrisherlein/about-ethics-1geh</guid>
      <description>&lt;p&gt;Without any doubts, I am very under level on this topic. Honesty goes first.&lt;/p&gt;

&lt;p&gt;That said... how many times do we stop writting code to reflex on how much impact it will have on the comunity we live into? Let me guess: not many. &lt;/p&gt;

&lt;p&gt;The World has moved faster than ever in 2020, and it still does in '21. That global ticket called COVID-19 put all of us hands on work for adapting, even for thoose who were the most anti virtual activists. And those tasks revealed a lot of who we are, how IT people think, work, imagine or even, move.&lt;/p&gt;

&lt;p&gt;We are one of the first industries that adopt remote work as usual, many years ago. And we created our tools, our methods, our culture. And we were pointed as the freaks. But now, almost every single industry is working completly or in part as we are used to.&lt;/p&gt;

&lt;p&gt;It is then in this cahotic context when we can really have a meassure about how much impact we made into people's life. And it is a bit scary to remember ourselves writting code without cocerns on if it could harm someone, or if we were dealing with some personal data. Or even beyond: how many times did we notice something smelt rare on the definitions we were given?&lt;/p&gt;

&lt;p&gt;Tons of times we had to deal with customer's or bosse's intentions we can disagree, but we still have to code. Did we do the enoug to protect everybody's integrity? Or have we protect our own integrity, keeping us as good citizens?&lt;/p&gt;

&lt;p&gt;There are two accepted and adopted ethics codes around:&lt;br&gt;
ACM: &lt;a href="https://www.acm.org/code-of-ethics" rel="noopener noreferrer"&gt;https://www.acm.org/code-of-ethics&lt;/a&gt;&lt;br&gt;
IEEE: &lt;a href="https://www.ieee.org/about/corporate/governance/p7-8.html" rel="noopener noreferrer"&gt;https://www.ieee.org/about/corporate/governance/p7-8.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But still, it looks a really underated topic in our community. I have never had the chance to discuss it in a work environment, for example.&lt;/p&gt;

&lt;p&gt;In other to improve our proffesion, my intention and commitment is to put this topic on the table every single time I can. This is my promisse to Touring and Ritchie. &lt;/p&gt;

&lt;p&gt;Furthermore, I want to motivate you to be conscious on the impact you are causing with your code... and to raise an alert every time you see something strange behind the scenes.&lt;/p&gt;

&lt;p&gt;Thans for the reading, and ethic hacking!&lt;/p&gt;

</description>
      <category>ethics</category>
      <category>development</category>
      <category>community</category>
    </item>
    <item>
      <title>Publics API authenticate</title>
      <dc:creator>Christian Herlein</dc:creator>
      <pubDate>Mon, 10 May 2021 12:58:10 +0000</pubDate>
      <link>https://dev.to/chrisherlein/publics-api-authenticate-56o4</link>
      <guid>https://dev.to/chrisherlein/publics-api-authenticate-56o4</guid>
      <description>&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%2Fkv6iljakbod7hh277evz.jpg" 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%2Fkv6iljakbod7hh277evz.jpg" alt="Alt Text" width="179" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario:
&lt;/h3&gt;

&lt;p&gt;Some time ago, a new project was presented to me. I had to design the solution.&lt;/p&gt;

&lt;p&gt;Among other stuff, that I will talk later, one of the challenges was about communicate a set of services that were expose to the public internet. Despite I was not comfortable about that, it was one of the requirements; a custom app had to be able to talk to the API directly, while most of the apps will talk to a specific API (entry point, &lt;strong&gt;EP&lt;/strong&gt;). This &lt;strong&gt;EP&lt;/strong&gt; then will have to talk to other services as well.&lt;/p&gt;

&lt;p&gt;Then, the problem was: How do I control that every request between two APIs were actually allowed to ask and read information?&lt;/p&gt;

&lt;p&gt;Every auth I had used at that time were in the form of: 1. I were provided a pair of key values to send in headers every time. 2. I had to ask for a new token every time I want to send a message.&lt;/p&gt;

&lt;p&gt;But this time I wanted to make something different, and put in practise an advice given to me by an older college: triangles tends to be safe.&lt;/p&gt;

&lt;h3&gt;
  
  
  The third guy:
&lt;/h3&gt;

&lt;p&gt;To make my triangle, I created a new API that was going to be the source of true for permissions. Lets name it &lt;strong&gt;SoT&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Then, the general algorithm was:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Every API will have its own secret key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SoT&lt;/strong&gt; will have everybody’s secrets key.&lt;/li&gt;
&lt;li&gt;When a request comes from &lt;strong&gt;EP&lt;/strong&gt;, a transaction will be created on &lt;strong&gt;SoT&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Every request will be signed by emitter with secret and transaction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SoT&lt;/strong&gt; will be the only capable of tell if a signature is right or not.&lt;/li&gt;
&lt;li&gt;Every time an API receives a requests, will ask to &lt;strong&gt;SoT&lt;/strong&gt; if request’s signature is valid.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Implementation:
&lt;/h3&gt;

&lt;p&gt;Actually, coding that solution was quite straight forward; I needed two clients components and the SoT controllers:&lt;/p&gt;

&lt;p&gt;From &lt;strong&gt;EP&lt;/strong&gt; ask for create and sign a transaction&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  transactionId = new uuid()
  sign = new Hash(EP_SECRET_KEY, transactionId)

  // EntryPoint as requester API name for signer field
  ok = sot.create(‘EntryPoint’, transactionId, sign)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Into &lt;strong&gt;SoT&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; remoteKey = keys.get(input.signer)
 if input.sign == new Has(remoteKey, input.transactionId)
   createTransaction()
 else
   Error(403, ‘Can not create transaction’)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;From a requested API (as endpoint middleware)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  if !sot.validate(input.sign, input.transactionId, input.signer)
    Error(403, ‘Invalid signature’)

  continue()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once a request was authenticated, other internal calls can be authed in the same way.&lt;/p&gt;

&lt;p&gt;About the secrets, they should be generated randomly in deploy time. Every time we deploy an API, we renew its secret and let &lt;strong&gt;SoT&lt;/strong&gt; know about the change. They are stored in env vars.&lt;br&gt;
Risks:&lt;/p&gt;

&lt;p&gt;Not really found a lot to concern about. As we keep secrets real secrets, we should have no concern. Who want to make unauthorized requests should know the secrets and the hash function implemented.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sum up:
&lt;/h3&gt;

&lt;p&gt;It’s quite easy to implement triangle authentications by our own with certain security level. What we need to care about is keep keys secrets and don’t expose our hash functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gretings:
&lt;/h3&gt;

&lt;p&gt;Thanks for the read. Any suggestions or comments are appreciated.&lt;/p&gt;

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