<?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: Robin-Manuel Thiel</title>
    <description>The latest articles on DEV Community by Robin-Manuel Thiel (@robinmanuelthiel).</description>
    <link>https://dev.to/robinmanuelthiel</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%2F161836%2Fce59444f-c223-40fb-aeb8-3ce1e040335b.jpeg</url>
      <title>DEV Community: Robin-Manuel Thiel</title>
      <link>https://dev.to/robinmanuelthiel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/robinmanuelthiel"/>
    <language>en</language>
    <item>
      <title>With the fall of Stack Overflow, AI Coding Assistants like GitHub Copilot will have a data problem!</title>
      <dc:creator>Robin-Manuel Thiel</dc:creator>
      <pubDate>Sun, 01 Sep 2024 12:42:47 +0000</pubDate>
      <link>https://dev.to/robinmanuelthiel/with-the-fall-of-stack-overflow-ai-coding-assistants-like-github-copilot-will-have-a-data-problem-36mi</link>
      <guid>https://dev.to/robinmanuelthiel/with-the-fall-of-stack-overflow-ai-coding-assistants-like-github-copilot-will-have-a-data-problem-36mi</guid>
      <description>&lt;p&gt;Stack Overflow shares website data with some of its most active members (how cool is that?), which is currently &lt;a href="https://observablehq.com/@ayhanfuat/the-fall-of-stack-overflow?ref=blog.pragmaticengineer.com" rel="noopener noreferrer"&gt;showing a dramatic decrease in traffic&lt;/a&gt;, which ML engineer Ayhan Fuat Çelik named "The Fall of Stack Overflow". As one of the biggest data sources of LLM trainings (especially those focussing on assisting with coding), Stack Overflow plays a critical role in the success of AI Coding Assistants like GitHub Copilot. Even though &lt;a href="https://blog.pragmaticengineer.com/are-reports-of-stackoverflows-fall-exaggerated/?ref=pumpingco.de" rel="noopener noreferrer"&gt;Gergely Orosz pointed out, that the reports of Stack Overflow's downfall might be exaggerated&lt;/a&gt;, the number of questions being asked on the platform is indeed decreasing.&lt;/p&gt;

&lt;p&gt;With fewer questions about current programming problems being asked on the public internet, the training data for the coding assistants of tomorrow gets reduced. Ironically, the coding assistants of today are one of the main reasons for the fall of Stack Overflow and why people ask their questions in private to an AI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why could this become problematic?
&lt;/h2&gt;

&lt;p&gt;AI Coding Assistants are based on Generative AI Models, which can only be as good as their training data. With less public knowledge on coding, how do we train models to solve the coding challenges of the programming languages, frameworks, and tools of the future?&lt;/p&gt;

&lt;p&gt;Developers don't have fewer questions, they just ask them to AI Assistants instead. Even if these AI Assistants would publish anonymized questions and answers to a public data set, it would not be good advice to train new AI Models on them, as training AI on AI-generated content risks poisoning the training data for future AI models. This can lead to a phenomenon called "model collapse," where errors accumulate over generations, resulting in nonsensical outputs. &lt;a href="https://www.scientificamerican.com/article/ai-generated-data-can-poison-future-ai-models/?ref=pumpingco.de" rel="noopener noreferrer"&gt;Experts warn that as AI content becomes more prevalent&lt;/a&gt;, it could bias models and degrade their quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Will AI Assistants have a Netflix Problem?
&lt;/h2&gt;

&lt;p&gt;With human-created data-sets seeing a dramatic increase in value for training Large Language Models like Open AI's GPT family, we are already seeing owners of these training sets like &lt;a href="https://www.theverge.com/2024/7/24/24205244/reddit-blocking-search-engine-crawlers-ai-bot-google?ref=pumpingco.de" rel="noopener noreferrer"&gt;Reddit guarding them and blocking automatic access&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In my opinion, the worst outcome of all this from a user experience perspective would be, if companies like Reddit or Stack Overflow came up with their own AI Assistants, which would then have exclusive access to their data. This is what I call the Netflix problem, referring to a time when Netflix had all existing shows and movies in their portfolio, and now we ended up with Amazon Prime Video, Disney+, Paramount and many more. The same happened to car sharing and E-Scooters.&lt;/p&gt;

&lt;p&gt;People don't want to ask 5 different AI coding Assistants for help, hoping that one of them was trained on data that could lead to an answer. They want one. There could be different ones on the market, but once they decide on one, they want to use it for everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Or maybe it is not a big problem at all?
&lt;/h2&gt;

&lt;p&gt;From my own experience, AI Coding Assistants work fantastic for narrowly scoped and straightforward questions. Whenever an issue becomes complex or might happen across multiple layers like programming language, framework, database driver, database type and so on, they still struggle, and I turn to Stack Overflow.&lt;/p&gt;

&lt;p&gt;We should probably take a look at which kind of questions are being asked less on Stack Overflow. If had to guess, I would say it's the straightforward and less complex ones. Maybe these could also be answered by AI models by taking the official and public documentation into their training sets.&lt;/p&gt;

&lt;p&gt;I'm sure, all this also applies to other industries that use AI Assistants and Copilots already. I am very curious to see, how this affects the quality of future AI applications.&lt;/p&gt;

</description>
      <category>githubcopilot</category>
      <category>ai</category>
      <category>llm</category>
      <category>data</category>
    </item>
    <item>
      <title>What we learned after spending 5,000 EUR on developer marketing</title>
      <dc:creator>Robin-Manuel Thiel</dc:creator>
      <pubDate>Tue, 27 Aug 2024 13:18:23 +0000</pubDate>
      <link>https://dev.to/robinmanuelthiel/what-we-learned-after-spending-5000-eur-on-developer-marketing-2lpl</link>
      <guid>https://dev.to/robinmanuelthiel/what-we-learned-after-spending-5000-eur-on-developer-marketing-2lpl</guid>
      <description>&lt;p&gt;For &lt;a href="https://spaceblocks.cloud" rel="noopener noreferrer"&gt;Space Blocks&lt;/a&gt;, a Developer Platform for Permission Management, we decided to spread the work through online marketing in various channels like Social Media, Google Ads, Newsletters, and YouTube Video Ads. Here is our wrap-up.&lt;/p&gt;

&lt;h2&gt;
  
  
  The campaigns
&lt;/h2&gt;

&lt;p&gt;We are targeting Software Developers with our product, and our main goal for the campaign was raising awareness of our existence. We wanted to let developers know that we offer an easy-to-use solution for all kinds of permission related features. We gave ourselves a budget of €5,000 and a time-span of one month to evaluate what I am now sharing here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Google Ads 👍
&lt;/h3&gt;

&lt;p&gt;We didn't hear many success stories about Google Ads so far, and so we have been careful with our spendings there, but still wanted to give it a try. &lt;strong&gt;Navigating through the &lt;a href="https://ads.google.com" rel="noopener noreferrer"&gt;Google Ads Console&lt;/a&gt; is a pain&lt;/strong&gt; and although you can probably configure everything, it is very overwhelming and contains a lot of new ad-specific vocabulary, which made it challenging to understand for beginners like us. &lt;strong&gt;Google lets you target specific locations (countries) and keyword "themes"&lt;/strong&gt;, from which they derive the actual keywords they are showing your ad on. You can edit those keywords later throughout the running campaign. If your ad will be shown, when a user searches for one of these keywords, depends on how much money you are willing to spend.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe87u8g3rnb9bx0ic3hla.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe87u8g3rnb9bx0ic3hla.png" alt="Preview of our Google Banner Ad" width="335" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We used the following configuration for the campaign.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Countries&lt;/strong&gt;: Latvia, Andorra, Liechtenstein, Armenia, Lithuania, Austria, Luxembourg, Azerbaijan, Malta, Moldova, Belgium, Monaco, Bulgaria, Netherlands, Croatia, Norway, Cyprus, Poland, Czech Republic, Portugal, Denmark, Romania, Estonia, Finland, San Marino, France, Slovakia, Georgia, Slovenia, Germany, Spain, Greece, Hungary, Sweden, Iceland, Switzerland, Ireland, Turkey, Italy, United Kingdom, United Arab Emirates, United States&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keyword themes&lt;/strong&gt;: app development, Access Control, software development, permissions, RBAC, access rights, permission checks, permissions for apps, permissions for developers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Max daily budget&lt;/strong&gt;: $20&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmn6yax8nttj34akpawad.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmn6yax8nttj34akpawad.png" alt="Results of the Google Ads campaign" width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With these values, we were able to achieve 360,000 impressions and 10,900 clicks over a total cost of €448. Not a crazy good result, but spending less than $500 to make 360,000 people aware of our product and have more than 10,000 people actually visiting the website is not too bad.&lt;/p&gt;

&lt;h3&gt;
  
  
  Non-skippable YouTube Video Ads 👎
&lt;/h3&gt;

&lt;p&gt;As at Space Blocks we are all big fans of watching YouTube videos on Technology and Programming content, we thought running video ads before those video was a good idea. &lt;strong&gt;When you create a Video Spot that is less than 15s, YouTube even lets you create it as a non-skippable(!) ad out of it&lt;/strong&gt;, which sounded very appealing to us.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vfrVJuUKikY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;YouTube Ads are scheduled through the same &lt;a href="https://ads.google.com" rel="noopener noreferrer"&gt;Google Ads Console&lt;/a&gt; as Google Ads and basically work the same in terms of targeting.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Countries&lt;/strong&gt;: Latvia, Andorra, Liechtenstein, Armenia, Lithuania, Austria, Luxembourg, Azerbaijan, Malta, Moldova, Belgium, Monaco, Bulgaria, Netherlands, Croatia, Norway, Cyprus, Poland, Czech Republic, Portugal, Denmark, Romania, Estonia, Finland, San Marino, France, Slovakia, Georgia, Slovenia, Germany, Spain, Greece, Hungary, Sweden, Iceland, Switzerland, Ireland, Turkey, Italy, United Kingdom, United Arab Emirates, United States&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audiences&lt;/strong&gt;: Technology Industry, Business Professionals, Technology, Cloud Services Power Users, Business Technology, Hosted Data &amp;amp; Cloud, Enterprise Software, Web Services, Web Design &amp;amp; Development, Business Creation, Recently started a Business, Starting a Business soon, &lt;em&gt;All Users of Space Blocks Website&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvn017b63b1li5y6owm4q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvn017b63b1li5y6owm4q.png" alt="Results of the YouTube non-skippable Ad campaign" width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The results were disappointing. Although spending much more money on YouTube than on Google Ads, only one third of impressions (105,000) were generated. With not even 500 clicks for more than €1,200, &lt;strong&gt;YouTube Ads had the worst performance of the entire campaign, in contrast to the highest production cost&lt;/strong&gt; and time of the video spot. (It turns out, that fitting content into 15s is much harder than expected, as every single frame counts).&lt;/p&gt;

&lt;h3&gt;
  
  
  Reddit Ads 👍
&lt;/h3&gt;

&lt;p&gt;As Reddit is popular among developers, we also wanted to run ads there. &lt;strong&gt;The experience of creating ads on Reddit, as well as their performance, was surprisingly&lt;/strong&gt; pleasant in contrast to Google.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zs47rev4x12mtalyugn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zs47rev4x12mtalyugn.png" alt="Preview of our Reddit Banner Ad" width="471" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reddit lets you target precisely in which Subreddits you want to display your ad and offers to extend this selection dynamically&lt;/strong&gt; using their algorithm, which we accepted.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Countries&lt;/strong&gt;: Latvia, Andorra, Liechtenstein, Armenia, Lithuania, Austria, Luxembourg, Azerbaijan, Malta, Moldova, Belgium, Monaco, Bulgaria, Netherlands, Croatia, Norway, Cyprus, Poland, Czech Republic, Portugal, Denmark, Romania, Estonia, Finland, San Marino, France, Slovakia, Georgia, Slovenia, Germany, Spain, Greece, Hungary, Sweden, Iceland, Switzerland, Ireland, Turkey, Italy, United Kingdom, United Arab Emirates, United States&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subreddits&lt;/strong&gt;: r/javascript, r/aws, r/developer, r/googlecloud, r/node, r/dotnet, r/reactjs, r/SaaS, r/devops, r/softwaredevelopment, r/ChatGPTCoding, r/cloudcomputing, r/programming, r/webdev, r/AZURE, r/csharp, r/LangChain, r/Cloud, r/micro_saas, r/AppDevelopers, r/AskProgramming, r/WebDeveloper (dynamic extension activated)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost-cap&lt;/strong&gt;: €2.00 per click&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7bfhuyqvq9cr49slei4l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7bfhuyqvq9cr49slei4l.png" alt="Results of the Reddit Ad campaign" width="800" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With a budget of €700, we were able to reach nearly 1.5 Million developers, from which approx. 3,000 clicked the ad and visited our website. This is many more impressions than on Google, but also fewer clicks for a comparable budget. &lt;strong&gt;For impressions, I would always choose Reddit&lt;/strong&gt;, although the idea, what &lt;strong&gt;many of them might have been bots&lt;/strong&gt; scraping Reddit leaves a bitter taste and might explain, why we were seeing fewer clicks. Bots usually don't click on ads.&lt;/p&gt;

&lt;h3&gt;
  
  
  DEV.to Ads 👎
&lt;/h3&gt;

&lt;p&gt;As regular readers of DEV.to, we also wanted to advertise there. We chose the smallest available campaign size, which runs for 7 days for $1,000.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyny8z73l7r6rqd6xlthx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyny8z73l7r6rqd6xlthx.png" alt="Preview of our DEV.to Banner Ad" width="500" height="752"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;This pricing tier does not allow to segment the target audience *&lt;/em&gt;(the larger ones do) but as on DEV.to, there are only developers anyway, this didn't bother us too much.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnc7ew9tfrtuadhnulc4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnc7ew9tfrtuadhnulc4.png" alt="DEV.to campaign results are sent to you in CVS / Excel format" width="286" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Over the 7 days that the campaign was running, we were able to generate 101,075 impressions and only 112 clicks. So either our banner ad was not very appealing (maybe we used too many emojis?) or DEV.to users just don't click on Banner Ads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hacker Newsletter Sponsoring 👎
&lt;/h3&gt;

&lt;p&gt;One last channel, we tried was newsletter sponsoring. I don't have the feeling, developers are overly into E-Mail newsletters, but we wanted to give it a try. The &lt;a href="https://hackernewsletter.com/" rel="noopener noreferrer"&gt;Hacker Newsletter&lt;/a&gt; has 60,000 subscribers and collects trending discussions on Y Combinator's popular &lt;a href="https://news.ycombinator.com/" rel="noopener noreferrer"&gt;Hacker News&lt;/a&gt; website.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj0mgbnj5j47ihrhbuakf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj0mgbnj5j47ihrhbuakf.png" alt="Sponsored Link in the Hacker Newsletter issue #700" width="680" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For $200, you can buy a "classified" (promoted) link for one issue of the newsletter. We gave it a try and &lt;strong&gt;did not register a single page visit from there.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A word on costs and offers
&lt;/h2&gt;

&lt;p&gt;If you sum up all the spendings in this article, you will come to the conclusion, that in total we spent more than €5,000. In reality though, both, Google and Reddit had special offerings at the time when we were running the campaigns, that we used.&lt;/p&gt;

&lt;p&gt;Google offered an additional credit of €800, when spending more than €1,200 on their ad platform. Reddit had a similar deal and offered $200 credits, after spending at least $100. &lt;strong&gt;Look out for this kind of deals, when running your own campaign.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What about Ad Blockers?
&lt;/h2&gt;

&lt;p&gt;Nearly all developers are very tech-savvy users and, I would guess, the vast majority of them use ad blockers (I do so myself). So it's a valid question, if banner ads are the right medium to reach them in the first place. I don't have a finite answer on that.&lt;/p&gt;

&lt;p&gt;Ad Blockers are the main reason why we chose YouTube Video Ads, as YouTube makes it increasingly hard to use Ad Blockers since they try to sell their Premium plan. The same goes for other media formats like Newsletters and Podcasts. Maybe a Banner Ad is not the right format anymore and our brains are so used to filtering them out? 🤔&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Hint: If you plan to run ads for any kind yourself, make sure to disable your own ad-blocker. Otherwise, most ad platforms won't work properly. Don't ask me, how long it took me to find out...&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Measure your success
&lt;/h2&gt;

&lt;p&gt;If you are really just after brand awareness, tracking impressions and clicks might be enough, but in most cases, you will want to know, how users interact with your website or product after clicking on an ad (e.g. pricing page visited, signed-up or booked-demo). For this, nearly all ad platforms let you define campaign goals in the form of events.&lt;/p&gt;

&lt;p&gt;You should absolutely track these events by embedding the according reporting scripts, which are often called pixels (Facebook Pixel, Reddit Pixel) into your website, so that the reporting tools of your ad platform can track them. It is advisable to also track the source of the traffic (e.g. Newsletter X, banner ad on website Y) with tools like the &lt;a href="https://support.google.com/analytics/answer/10917952?hl=en#zippy=%2Cin-this-article" rel="noopener noreferrer"&gt;Google Analytics URL Builder&lt;/a&gt;, in case an ad platform does not support event tracking. This gives each ad network a unique campaign link, and you can also validate their reports on your end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In total, we reached approx. 2,000,000 users (impressions) and could show them the existence of our product, from which we could convince 14,000 users to click on one of our ads and visit our website. With a budget of only €5,000, I call this a mild success, but not a huge one.&lt;/p&gt;

&lt;p&gt;It is worth to mention that &lt;strong&gt;Google Analytics tracked much fewer sessions than the ad networks reported clicks&lt;/strong&gt;, which led us to the conclusion, that some clickers closed the website immediately. It is advisable to track the source of the traffic (e.g. with the Google Analytics URL Builder) and give each ad network a unique campaign link.&lt;/p&gt;

&lt;p&gt;In summary, banner and video ads targeted towards developers seem to work much better for awareness than for clicks - meaning if you want to let developers know, that your product exists, it might be a useful tool, but if your goal is engagement, I wouldn't count our campaigns as a success.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Understanding the Difference Between Authentication and Authorization</title>
      <dc:creator>Robin-Manuel Thiel</dc:creator>
      <pubDate>Thu, 09 May 2024 07:29:00 +0000</pubDate>
      <link>https://dev.to/spaceblocks/understanding-the-difference-between-authentication-and-authorization-1kg9</link>
      <guid>https://dev.to/spaceblocks/understanding-the-difference-between-authentication-and-authorization-1kg9</guid>
      <description>&lt;p&gt;In the realm of software development, particularly in the context of security, two terms that often come up are "authentication" and "authorization." While they sound similar and are often used interchangeably, they serve distinct purposes in ensuring the security and integrity of software systems. Let's delve into the specifics of each and explore how they differ, along with some technologies commonly used to implement them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication: Who Are You?
&lt;/h2&gt;

&lt;p&gt;Authentication is the process of verifying the identity of a user or entity attempting to access a system or resource. In simpler terms, authentication answers the question, "Who are you?" This process typically involves the user providing some form of credentials, such as a username and password, biometric data, security tokens, or digital certificates. The system then validates these credentials against stored records to determine whether the user is who they claim to be.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technologies for Authentication:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Username and Password&lt;/strong&gt;: This is the most common form of authentication, where users provide a unique username and a corresponding password.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Biometric Authentication&lt;/strong&gt;: With advancements in technology, biometric authentication methods such as fingerprint scanning, facial recognition, iris scanning, and voice recognition are becoming increasingly popular for user authentication.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Tokens&lt;/strong&gt;: Security tokens, such as smart cards or hardware tokens, generate one-time passwords or cryptographic keys that users must provide along with their other credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OAuth 2.0&lt;/strong&gt;: OAuth is an open-standard authorization protocol that allows users to access resources from one website using their credentials from another website or service without exposing their password. It is commonly used for granting third-party applications limited access to a user's resources without exposing their credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Passwordless Authentication&lt;/strong&gt;: Passwordless authentication eliminates the need for traditional passwords and relies on alternative methods such as magic links sent via email, SMS-based one-time passcodes (OTPs), or authentication apps. This approach enhances security and user experience by reducing the risk of password-related attacks such as phishing and credential stuffing, while also simplifying the login process for users.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Authorization: What Are You Allowed to Do?
&lt;/h2&gt;

&lt;p&gt;Authorization, on the other hand, comes into play after authentication and determines what actions an authenticated user or entity is permitted to perform within the system. Authorization answers the question, "What are you allowed to do?" It involves defining and enforcing access controls based on the user's identity, role, or other attributes.&lt;/p&gt;

&lt;p&gt;Authorization mechanisms specify the level of access granted to users for various resources or functionalities within the system. This could include read-only access, write access, administrative privileges, or custom permissions tailored to specific roles or individuals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technologies for Authorization:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OAuth 2.0&lt;/strong&gt;: While OAuth is primarily an authentication protocol, it also has provisions for authorization through the use of access tokens. OAuth 2.0 enables third-party applications to access resources on behalf of a user with their consent, following a predefined authorization flow. Read, why Access Tokens are not sufficient for fine-grained access control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Role-Based Access Control (RBAC)&lt;/strong&gt;: RBAC is a widely used authorization model that assigns permissions to roles rather than individual users. Users are then assigned one or more roles that determine their access rights within the system. RBAC simplifies access management by grouping users based on their job functions or responsibilities. This is, what Space Blocks Permissions is doing for fine-grained access control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attribute-Based Access Control (ABAC)&lt;/strong&gt;: ABAC defines access controls based on attributes associated with the user, the resource being accessed, and the environment. Policies are defined using attributes such as user roles, location, time of access, and other contextual information to make access decisions dynamically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access Control Lists (ACLs)&lt;/strong&gt;: ACLs are a mechanism for defining and enforcing access controls on individual resources. They specify which users or groups are granted access to a particular resource and what operations they are allowed to perform.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Don't build Authentication or Authorization yourself!
&lt;/h2&gt;

&lt;p&gt;Implementing both, Authentication and Authorization on your own can be challenging and complex. You want to make sure, to follow all security requirements for storing user-passwords, for example.&lt;/p&gt;

&lt;p&gt;This is, why most developers rely on external tools for Authentication and others for Authorization, which can then be included into their apps. &lt;a href="https://www.spaceblocks.cloud"&gt;Space Blocks Permissions&lt;/a&gt; is a system to integrate fine-grained access control quickly into your apps with a few lines of code, so developers can focus on their core business. If you need to add permissions to your app, give it a try with the free Developer Tier.&lt;/p&gt;

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

&lt;p&gt;In summary, while authentication verifies the identity of users or entities accessing a system, authorization determines what actions they are allowed to perform once authenticated. Understanding the distinction between these two concepts is crucial for designing secure and robust software systems. By implementing appropriate authentication and authorization mechanisms using technologies such as those mentioned above, developers can ensure that their applications remain secure, and only authorized users have access to sensitive resources.&lt;/p&gt;

</description>
      <category>authorization</category>
      <category>authentication</category>
      <category>permissions</category>
    </item>
    <item>
      <title>Google Zanzibar implementations</title>
      <dc:creator>Robin-Manuel Thiel</dc:creator>
      <pubDate>Wed, 08 May 2024 05:22:00 +0000</pubDate>
      <link>https://dev.to/spaceblocks/google-zanzibar-implementations-56f8</link>
      <guid>https://dev.to/spaceblocks/google-zanzibar-implementations-56f8</guid>
      <description>&lt;p&gt;Authentication is hard. Implementing fine-grained access control is even harder. Whoever tried to build a sophisticated authentication system themselves knows that. And those who didn't are well advised by not trying to. Proper Authentication is so hard, that 2020 &lt;a href="https://research.google/pubs/pub48190/"&gt;Google published a research paper&lt;/a&gt; about the numerous challenges and complexity they faced when implementing a global permission system for YouTube, Google Drive and Google Photos. This research paper is called "Zanzibar".&lt;/p&gt;

&lt;p&gt;What the paper is lacking are implementation details. And since its release, some brave developers tried to implement an Authentication system along Google's findings. Here is a list of Google Zanzibar implementations:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;1. Space Blocks Permissions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://spaceblocks.cloud/"&gt;Space Blocks&lt;/a&gt; has built &lt;strong&gt;&lt;em&gt;the most complete&lt;/em&gt;&lt;/strong&gt; implementation of the Google Zanzibar research paper. It supports hierarchical permission trees, inheritance of access rights and custom roles. It can be hosted on your own servers or in the Space Blocks Cloud, where it provides high-availability and short response times.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Completeness&lt;/strong&gt;: Most complete and feature-rich Zanzibar implementation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy to integrate&lt;/strong&gt;: Permissions checks are integrated with a few lines of code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GUI&lt;/strong&gt;: Graphical Editor for designing and visualizing permission trees.&lt;strong&gt;‍&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low Learning Curve&lt;/strong&gt;: No proprietary modeling language.
****&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SDK Availability&lt;/strong&gt;: Only for .NET, JavaScript and React. Other platforms need to use the REST-API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Additional API endpoint required&lt;/strong&gt;: Your backend might need to implement additional API endpoints for your frontend&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;2. OpenFGA&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Auth0’s OpenFGA project focuses on delivering a universal authorization system. The name stands for “Fine Grained Authorization,” emphasizing a granular approach to modeling authorization that can handle diverse use cases. It is owned by the Cloud Native Foundation.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Granularity&lt;/strong&gt;: Allows fine-grained control over permissions, catering to complex authorization scenarios.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open-Source Community&lt;/strong&gt;: Community contributions and improvements are encouraged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: OpenFGA aims for reliability and performance.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Missing Features:&lt;/strong&gt; Operation for Listing all items a user has access to is incomplete&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Steep Learning Curve&lt;/strong&gt;: Understanding the modeling language schema may require some effort.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;‍&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;3. ORY Keto&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;An open-source implementation of the Google Zanzibar paper exists in the form of the ****ORY Keto project. The first working version was released, aiming to bring the concepts from the paper to practical use. It can be employed to manage permissions and roles in various applications and websites.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open-Source Community&lt;/strong&gt;: Being open source, it benefits from community contributions and improvements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast and Efficient&lt;/strong&gt;: ORY Keto aims for high performance, ensuring rapid decision-making.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Steep Learning Curve&lt;/strong&gt;: The granular permission language might require some learning and understanding.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;4. Permify&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Permify is another open-source authorization service for creating and managing scalable authorization systems using fine-grained permissions. It draws inspiration from Google’s Zanzibar paper and offers various binding and crafting options, allowing engineers to work with performant, observable, and secure permission systems.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Integration&lt;/strong&gt;: Integrates into many Identity Providers like Okta and Azure Active Directory&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Granularity&lt;/strong&gt;: Allows fine-grained control over permissions, catering to complex authorization scenarios.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open-Source Community&lt;/strong&gt;: Benefits from community contributions.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Steep Learning Curve&lt;/strong&gt;: Understanding the modeling schema may require effort.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>permissions</category>
      <category>authorization</category>
      <category>google</category>
      <category>zanzibar</category>
    </item>
    <item>
      <title>Run Large and Small Language Models locally with ollama</title>
      <dc:creator>Robin-Manuel Thiel</dc:creator>
      <pubDate>Tue, 07 May 2024 09:37:30 +0000</pubDate>
      <link>https://dev.to/robinmanuelthiel/run-large-and-small-language-models-locally-with-ollama-48lh</link>
      <guid>https://dev.to/robinmanuelthiel/run-large-and-small-language-models-locally-with-ollama-48lh</guid>
      <description>&lt;p&gt;Since ChatGPT, we all know at least roughly what Large Language Models (LLMs) are. You might have heard that they require an immense amount of GPU power to run. But did you know, there are also smaller and less powerful versions of some models (SLMs) that you can run locally on your computer?&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Download and install &lt;a href="https://ollama.com/download"&gt;ollama&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Download and install &lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this tutorial, we use ollama to download a model onto your machine and run it there. Despite you have an absolute power house with lots of GPU power in front of you, you might want to try with smaller models, called Small Language Models or SLMs like &lt;a href="https://ollama.com/library/llama3"&gt;Llama 3 8B&lt;/a&gt; from Meta or &lt;a href="https://ollama.com/library/phi3"&gt;Phi-3 Mini 3.8B&lt;/a&gt; from Microsoft.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run a model locally with ollama
&lt;/h2&gt;

&lt;p&gt;Before we can communicate with a model via ollama, we need to start ollama. The ollama app is basically just a small web server that runs locally on your machine and lets you communicate with the models (by default on &lt;a href="http://localhost:11434"&gt;http://localhost:11434&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Run the following command in the Terminal to start the ollama server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ollama serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can open a separate Terminal window and run a model for testing. If the model you want to play with is not yet installed on your machine, ollama will download it for you automatically. You can find a full list of available models and their requirements at the &lt;a href="https://ollama.com/library"&gt;ollama Library&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Run the following command to run the small &lt;a href="https://ollama.com/library/phi3"&gt;Phi-3 Mini 3.8B&lt;/a&gt; model from Microsoft.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ollama run phi3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can interact with the model and write some prompts right at the command line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5tzmkzddlnnt8ewb4hq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5tzmkzddlnnt8ewb4hq.png" alt="Interacting with a model locally through the command line with ollama" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Chat with your own data locally
&lt;/h2&gt;

&lt;p&gt;For the whole ChatGPT like experience, where we can also chat with our own data or web sources, we don’t just want to prompt the model through the terminal.&lt;/p&gt;

&lt;p&gt;Luckily, there are some open-source projects like &lt;a href="https://github.com/open-webui/open-webui"&gt;Open WebUI&lt;/a&gt;, which provide a web-based experience similar to ChatGPT, that you can also run locally and point to any model. To start the Open WebUI Docker container locally, run the command below in your Terminal (make sure, that &lt;code&gt;ollama serve&lt;/code&gt; is still running).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --rm -p 8080:8080 \
  --add-host=host.docker.internal:host-gateway \
  -v open-webui:/app/backend/data \
  --name open-webui \
  ghcr.io/open-webui/open-webui:main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can open your browser at &lt;a href="http://localhost:8080"&gt;http://localhost:8080&lt;/a&gt;, and create an account. No worries, it all stays local, and you don’t even have to use a real E-Mail address.&lt;/p&gt;

&lt;p&gt;Once logged in, you can choose a model in the top-bar of Open WebUI and start chatting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftbccdzvx16cqukb2xijh.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftbccdzvx16cqukb2xijh.jpeg" alt="Running Open WebUI locally connected to ollama" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Running Open WebUI locally connected to ollama&lt;br&gt;
I would also like to encourage you to play with the Documents section, to perform some &lt;a href="https://docs.openwebui.com/tutorial/rag/"&gt;Retrieval Augmented Generation (RAG)&lt;/a&gt; with your local models!&lt;/p&gt;

&lt;p&gt;Now enjoy playing with Small Language Models on your computer! 🎉&lt;/p&gt;

</description>
      <category>llm</category>
      <category>ai</category>
      <category>slm</category>
      <category>ollama</category>
    </item>
    <item>
      <title>What is a JWT and why is it not sufficient for fine-grained access control</title>
      <dc:creator>Robin-Manuel Thiel</dc:creator>
      <pubDate>Tue, 07 May 2024 08:46:00 +0000</pubDate>
      <link>https://dev.to/spaceblocks/what-is-a-jwt-and-why-is-it-not-sufficient-for-fine-grained-access-control-5aa3</link>
      <guid>https://dev.to/spaceblocks/what-is-a-jwt-and-why-is-it-not-sufficient-for-fine-grained-access-control-5aa3</guid>
      <description>&lt;p&gt;While JWT (JSON Web Tokens) and session-based authentication mechanisms are robust tools for authenticating users and managing sessions, they fall short when it comes to fine-grained access control (FGA), which is where Space Blocks Permissions come into play.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication vs. Authorization
&lt;/h2&gt;

&lt;p&gt;In the realm of securing digital systems, two fundamental concepts often come into play: &lt;em&gt;authentication&lt;/em&gt; and &lt;em&gt;authorization&lt;/em&gt;. While authentication verifies the identity of a user, authorization dictates what actions they are allowed to perform within a system. So authentication is answering the question of &lt;em&gt;whom&lt;/em&gt; the user is. Authorization answers the question of &lt;em&gt;what&lt;/em&gt; the user is allowed to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does JWT work?
&lt;/h2&gt;

&lt;p&gt;JWT (JSON Web Token) is a digitally signed JSON document, which includes information about the current user. It usually gets issued to the user by the identity provider, after a user signed in successfully. With every request, the user then sends the JWT to the backend, which can then verify its authenticity at the identity provider and, in case of a positive outcome, decide to let the user do, what they want to do.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8p7m91v0vb7o6fdu6qj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8p7m91v0vb7o6fdu6qj.png" alt="Example of a JWT from jwt.io" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The information about the user in the JWT’s payload are called claims. The &lt;a href="https://www.iana.org/assignments/jwt/jwt.xhtml#claims"&gt;JWT Standard defines official claims&lt;/a&gt;, that a token can have, but any identity provider can also add custom claims. A JWT can hold any kind of information, but usually, you can find the following claims:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;iss&lt;/code&gt; (issuer): Issuer of the JWT&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sub&lt;/code&gt; (subject): Subject of the JWT (the user)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aud&lt;/code&gt; (audience): Recipient for which the JWT is intended&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;scope&lt;/code&gt; (scope): Actions for which the JWT is intended&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;exp&lt;/code&gt; (expiration time): Time after which the JWT expires&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nbf&lt;/code&gt; (not before time): Time before which the JWT must not be accepted for processing&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;iat&lt;/code&gt; (issued at time): Time at which the JWT was issued; can be used to determine the age of the JWT&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When it comes to authorization (checking, what a user is allowed to do), the &lt;code&gt;aud&lt;/code&gt; (audience) and &lt;code&gt;scope&lt;/code&gt; (scope) claims of a JWT are interesting. &lt;/p&gt;

&lt;p&gt;By checking the audience, a backend service can check, if a caller, that presents a certain token should be allowed to communicate with a specific backend or service (the audiences).&lt;/p&gt;

&lt;p&gt;When defining APIs, developers often add scopes like &lt;code&gt;read:secrets&lt;/code&gt; or &lt;code&gt;write:secrets&lt;/code&gt; to their routes. Depending on how the user acquired the Access Token and which permissions that user has, different scopes are listed in a JWTs claims. Backend services can check these scopes against the ones they defined as required for their APIs, to decide if a user is allowed to call a certain API method or not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why JWTs are insufficient for fine-grained access control
&lt;/h2&gt;

&lt;p&gt;As you might have noticed in the example above, JWT claims like audience and scope can only be used to check, if a user can call a certain API method or interact with a certain service at all. It’s all or nothing. The &lt;code&gt;read:secrets&lt;/code&gt; scope either allows a user to read secrets in your application or not.&lt;/p&gt;

&lt;p&gt;The reality often looks different. In most applications, where users collaborate with and share resources among each other, they have different permissions on different resources. A user might have read and write permissions to all of their own folders, but only read permissions to those that got shared by a teammate. Some permissions can also imply access to other resources without explicitly mentioning them. Read access to a folder usually also implies access to the files and sub-folder within the shared folder. &lt;/p&gt;

&lt;p&gt;JWTs are great and have their place in the authorization space, but should only be used to determine if a user should be let into a system and how far. When it comes to fine-grained access control on resource level, a more sophisticated approach like Space Blocks Permissions is needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Permissions as a Service with Space Blocks
&lt;/h2&gt;

&lt;p&gt;With the &lt;a href="https://www.spaceblocks.cloud"&gt;Space Blocks Permissions&lt;/a&gt; service, you can offload the burden of managing permissions, roles, groups and inheritance to our &lt;em&gt;Permissions as a Service&lt;/em&gt; system and focus on your core project. You can define the structure of your resources and their relationships, define permissions for them, create roles and then just let us know, whenever permissions got assigned or changed.&lt;/p&gt;

&lt;p&gt;Your backend can still use JWT for basic authentication, but can check the Space Blocks API for fine-grained access control, once a user got let into your system. &lt;/p&gt;

&lt;p&gt;You can integrate Space Blocks into your backend code with a few lines of code and completely for free in the Developer Tier.&lt;/p&gt;

</description>
      <category>permissions</category>
      <category>rbac</category>
      <category>jwt</category>
    </item>
    <item>
      <title>The ultimate guide to Git Hooks</title>
      <dc:creator>Robin-Manuel Thiel</dc:creator>
      <pubDate>Tue, 23 May 2023 09:24:00 +0000</pubDate>
      <link>https://dev.to/robinmanuelthiel/the-ultimate-guide-to-git-hooks-53c4</link>
      <guid>https://dev.to/robinmanuelthiel/the-ultimate-guide-to-git-hooks-53c4</guid>
      <description>&lt;h2&gt;
  
  
  What are Git Hooks, and why should I use them?
&lt;/h2&gt;

&lt;p&gt;Git Hooks are a Git feature, which allows developers to execute scripts at certain points in their Git lifecycle, like before accepting a commit, before pushing to a remote repository or before accepting a commit message. Git Hooks can be used to  "shift left" and automate tasks and enforce policies throughout the Git workflow.&lt;/p&gt;

&lt;p&gt;Git Hooks live in the &lt;code&gt;.git/hooks&lt;/code&gt; folder of a repository. Here, we can place scripts with the same name as the Git Hooks they should execute on (max. one per hook). Below, an example which checks the commit message for a certain pattern.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;MESSAGE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; 
&lt;span class="nv"&gt;COMMITFORMAT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"^(feat|fix|docs|style|refactor|test|chore|perf|other)(&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="s2"&gt;(.*)&lt;/span&gt;&lt;span class="se"&gt;\)&lt;/span&gt;&lt;span class="s2"&gt;)?: #([0-9]+) (.*)$"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MESSAGE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;~ &lt;span class="nv"&gt;$COMMITFORMAT&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Your commit was rejected due to the commit message. Skipping..."&lt;/span&gt;   
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep in mind, that each script in this folder has to be marked as executable by running &lt;code&gt;chmod +x pre-commit-msg&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can find more information and a list of available Git Hooks at &lt;a href="https://githooks.com"&gt;githooks.com&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to use them for?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Check commit messages:&lt;/strong&gt; Especially useful, if you use &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/"&gt;conventional commits&lt;/a&gt;. Also, to avoid the famous "WIP" or "fix" commit messages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check coding style and Linters:&lt;/strong&gt; A no-brainer. Nothing is more frustrating than going back to your code and fix that trailing space, after the CI pipeline failed because of it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check for secrets:&lt;/strong&gt; (Optional) We should check our code for accidentally checked-in secrets, like passwords or connection strings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build and Test:&lt;/strong&gt; (Optional) At least before pushing changes to a remote, we could make sure the code builds and the tests pass.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Problems
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can be bypassed
&lt;/h3&gt;

&lt;p&gt;As Git Hooks can be bypassed. For example, with the &lt;code&gt;--no-verfify&lt;/code&gt; flag for the &lt;code&gt;git commit&lt;/code&gt; command. So we should never rely on their execution but rather see them as a helper to avoid frustration amongst developers, when they find their Pull Request checks failing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As we can not rely on their execution, Git Hook checks should be repeated when checking the Pull Request on the server!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Not installed to each development environment by default
&lt;/h3&gt;

&lt;p&gt;As Git Hooks live in the &lt;code&gt;.git/hooks&lt;/code&gt; folder and the &lt;code&gt;.git&lt;/code&gt; folder itself is not part of the version control, scripts that are placed into that folder will not be checked in. So new developers that are cloning the repository won't have the Git Hooks in their local .git folder. Also, remote environments, like GitHub's In-Browser editing or &lt;a href="https://code.visualstudio.com/docs/devcontainers/containers"&gt;Dev Containers&lt;/a&gt; won't have the Git Hooks setup by default.&lt;/p&gt;

&lt;p&gt;A common practice around this behavior is placing the scripts into a &lt;code&gt;.githooks&lt;/code&gt; folder in the repository root, and then configuring Git to use its Hooks from there with the &lt;code&gt;git config core.hooksPath .githooks&lt;/code&gt; command. This allows to check in the scripts into version control, but the command still needs to be run in every new environment and won't make the Hooks available by default on new machines or remote environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependencies might not be installed
&lt;/h3&gt;

&lt;p&gt;Most scripts for checking coding style violations or commit message patterns aren't as basic as the one from above but use other tools like &lt;a href="https://prettier.io/"&gt;Prettier&lt;/a&gt;, &lt;a href="https://eslint.org/"&gt;ESLint&lt;/a&gt; or &lt;a href="https://github.com/editorconfig-checker/editorconfig-checker"&gt;editorconfig-checker&lt;/a&gt; for Coding Style checks or &lt;a href="https://jorisroovers.com/gitlint/latest/"&gt;Gitlint&lt;/a&gt; (highly recommended) for commit message policies. These tools might not be installed on new or remote environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing Git Hooks (and their dependencies) with pre-commit
&lt;/h2&gt;

&lt;p&gt;To deal with the problems from above, there are many tools out there which make working with Git Hooks easier and more straight-forward. Amongst the Node.js and JavaScript community, &lt;a href="https://typicode.github.io/husky/"&gt;Husky&lt;/a&gt; gained some popularity, as it natively integrates into the &lt;code&gt;package.json&lt;/code&gt; file, where app dependencies and development dependencies are managed.&lt;/p&gt;

&lt;p&gt;As I deal with projects across different programming languages and frameworks, I was looking for a more generic approach, which can be used with any project. The tool that convinced me the most is &lt;a href="https://pre-commit.com/"&gt;pre-commit&lt;/a&gt;, as it&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;manages and installs Git Hooks&lt;/li&gt;
&lt;li&gt;manages and installs dependencies (= tools, that my Git Hooks use)&lt;/li&gt;
&lt;li&gt;can be run in CI pipelines to check, if Git Hooks haven't been skipped&lt;/li&gt;
&lt;li&gt;is technology independent (in contrast to popular Husky)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The configuration for pre-commit is stored in a &lt;code&gt;.pre-commit-config.yaml&lt;/code&gt; file at the repository root and contains the hooks to configure and the tools that should be executed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;default_install_hook_types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;pre-commit&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;pre-push&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;commit-msg&lt;/span&gt;

&lt;span class="na"&gt;repos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/pre-commit/pre-commit-hooks&lt;/span&gt;
  &lt;span class="na"&gt;rev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v4.0.1&lt;/span&gt;
  &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check, that no large files have been committed&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;check-added-large-files&lt;/span&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/editorconfig-checker/editorconfig-checker.python&lt;/span&gt;
  &lt;span class="na"&gt;rev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2.7.1'&lt;/span&gt;
  &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check EditorConfig&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;editorconfig-checker&lt;/span&gt;
    &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ec&lt;/span&gt;
    &lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pre-push"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/jorisroovers/gitlint&lt;/span&gt;
  &lt;span class="na"&gt;rev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v0.19.1&lt;/span&gt;
  &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lint commit messages&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gitlint&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gitlint-ci&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;--commits'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;origin/main..HEAD'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Installing Git Hooks for each developer
&lt;/h2&gt;

&lt;p&gt;The configuration above allows to manage Git Hooks and their dependencies centrally in the repository. But the pre-commit tool itself still needs to be installed on each machine. Once installed, the hooks (and their dependencies) can be &lt;a href="https://pre-commit.com/#install"&gt;installed&lt;/a&gt; with a single command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pre-commit &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cross-Checking Git Hooks in the CI pipeline
&lt;/h2&gt;

&lt;p&gt;As Git Hooks can be bypassed, it is highly recommended to cross-check them in Pull Request Checks or the CI pipeline. This is another reason, why I like pre-commit so much: The scripts can be executed at-hoc for checking the current Git repository and its commits for violations.&lt;/p&gt;

&lt;p&gt;With GitHub Actions for example, you can check Pull Requests with the following workflow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PR Check&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pr-check&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install pre-commit&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pip install pre-commit&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check commits&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pre-commit run --hook-stage manual&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mitigate violations
&lt;/h2&gt;

&lt;p&gt;But what to do, when Pre-Push or Pull Request checks find policy violations in our code or commit messages, but the commit is already created and part of the current branch's history? &lt;/p&gt;

&lt;p&gt;In case of a committed file that needs to be adjusted, the history of the current branch can be soft-reset to undo all commits that happened on that branch. Don't worry, your work won't be lost. This will put all modifications back to the list of uncommitted changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout pr_branch
git reset &lt;span class="nt"&gt;--soft&lt;/span&gt; main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before creating a commit, we can now adjust the files. Afterward, we can create a new commit without the violation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"commit message goes here"&lt;/span&gt;
git push &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To change a commit message afterward, we can follow a &lt;a href="https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/changing-a-commit-message"&gt;comprehensive Guide from GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Both, resetting the history and changing commit messages is annoying. To avoid that, it is generally recommended to do most checks at the pre-commit level.&lt;/p&gt;

</description>
      <category>git</category>
      <category>hooks</category>
      <category>githooks</category>
    </item>
  </channel>
</rss>
