There's no place like 127.0.0.1.

SovereignRAG 1.0.0: Offline, Git-Aware Security Code Auditing

I’ve been building SovereignRAG, my fully offline RAG pipeline for security code auditing. It just reached 1.0.0.

This release is not just a version bump. It adds Git-aware analysis, Markdown ingestion, cited findings, better Ollama workflows, and a proper documentation site. It also includes a troubleshooting guide born from real pain, because nothing documents a feature better than watching it fail in your face.

What SovereignRAG is

SovereignRAG ingests security reference documents, such as OWASP guides, cheat sheets, and internal standards, into a local vector database. Then it analyzes source files against that knowledge using a local LLM served by Ollama.

SovereignRAG Updates

Yesterday I made a batch of changes to SovereignRAG that I had been putting off for a while: Markdown support in the ingestion pipeline and mandatory source citations in the reports.

The practical problem was straightforward. A significant portion of OWASP documentation doesn’t come as PDF — it comes as Markdown. Without .md support, I was leaving out of context exactly the docs that matter most in a vulnerability scanner. Now the project recursively discovers both PDFs and Markdown files inside any directory passed via --docs-dir, no need to list files individually.

Evoluindo o HADES

Este post descreve a evolução do HADES na detecção de URLs fraudulentas sem depender de serviços pagos.
O foco foi fortalecer a detecção com código próprio, heurísticas locais (PT/BR) e fontes públicas abertas, mantendo controle total do pipeline.

Nota: o CNPJ presente nos exemplos foi alterado para 11917932300169.
O objetivo é ilustrar o caso, não expor pessoas físicas ou jurídicas reais.


1) Problema inicial: heurística simples falha com golpes locais

O HADES usava regras simples: palavras suspeitas em inglês (login/verify), HTTP sem TLS, IP na URL, subdomínios excessivos e domínio recém-registrado.
Essas regras funcionam para exemplos didáticos, mas falham com golpes brasileiros.

Evolving HADES

This post describes how HADES evolved to detect fraudulent URLs without relying on paid services.
The focus was to strengthen detection with in-house code, local heuristics (PT/BR), and open public sources, while keeping full control of the pipeline.

Note: the CNPJ used in the examples was changed to 11917932300169.
The goal is to illustrate the case, not to expose real individuals or companies.

Note #2: CNPJ is the Brazilian business tax ID, similar to the EIN in the U.S.

Meu site agora está disponível via rede Tor

Recentemente, tive a sorte de conseguir um notebook Dell incrível em um bota-fora da empresa. Conseguir parcelar e pagar um preço acessível foi demais! Não é um equipamento cheio de firulas ou especificações mirabolantes, mas me deu uma alegria imensa colocar as mãos em uma máquina que, com um pouco de dedicação, se transforma em uma ferramenta poderosa.

Essa experiência me lembra muito de quem eu sempre fui. Não é só nostalgia de “era BBS”, mas sim uma continuidade. Naquela época, tudo era mais manual: desmontar coisas na mesa da cozinha, ajustar uns cabos, configurar IRQs e testar configurações até que funcionassem, e persistir mesmo quando nada parecia fazer sentido. Era teimosia e liberdade. Hoje, só mudaram os cabos, mas o espírito permanece o mesmo.

My website available via Tor network

Recently, I was lucky enough to pick up an amazing Dell laptop during a company clearance sale. Being able to split the payments and get it for a ridiculously good price was the icing on the cake. It’s not some overhyped, flashy machine full of unnecessary specs - but putting my hands on a device that turns into a powerful tool with a bit of care and intention brought me genuine joy.

Como verificar as assinaturas do meu site

Mudança na assinatura GPG do meu website

Não me lembro exatamente mas acredito que a pelo menos dois anos eu assino as páginas HTML do meu site com GPG, faço isso para praticar soberania, autenticidade até mesmo promover ferramentas que auxiliam na privacidade.

Inicialmente eu deixava a assinatura GPG embutida no próprio conteúdo HTML, por exemplo:

<!--
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

- -->
<!doctype html>
<html lang=en>
<head>
    <meta charset=utf-8>
    <meta http-equiv=X-UA-Compatible content="IE=edge">
    <meta name=viewport content="width=device-width,initial-scale=1">
    <meta property="og:title" content="What I’d Tell My 23-Year-Old Self">
    <meta property="og:description" content="If I could whisper to my 23-year-old self, I’d tell him this:

    Stop wasting time worrying about what people think.
    Pour your energy into building, into creating, into making something that’s yours.
    And never forget: everything is impermanent — every victory, every failure, every storm.

    That truth alone is enough to keep you moving forward.">
    <meta property="og:url" content="https://adlermedrado.com.br/missives/what-id-tell-my-23-year-old-self/">
    <meta property="og:site_name" content="Adler Medrado's corner of the web">
    <meta property="og:type" content="article">
    <meta property="og:image" content="/images/default-og-image.png">
    <meta name=twitter:card content="summary_large_image">
    <meta name=twitter:title content="What I’d Tell My 23-Year-Old Self">
    <meta name=twitter:description content="If I could whisper to my 23-year-old self, I’d tell him this:

    Stop wasting time worrying about what people think.
    Pour your energy into building, into creating, into making something that’s yours.
    And never forget: everything is impermanent — every victory, every failure, every storm.

    That truth alone is enough to keep you moving forward.">
    <meta name=twitter:image content="/images/default-og-image.png">
    <title>What I’d Tell My 23-Year-Old Self</title>
    <meta name=description content="If I could whisper to my 23-year-old self, I’d tell him this:

    Stop wasting time worrying about what people think.
    Pour your energy into building, into creating, into making something that’s yours.
    And never forget: everything is impermanent — every victory, every failure, every storm.

    That truth alone is enough to keep you moving forward.">
    <link rel=author href=/humans.txt>
    <link rel=icon type=image/png href=/images/favicon.png>
    <link rel=canonical href=https://adlermedrado.com.br/missives/what-id-tell-my-23-year-old-self/>
    <link href=/css/styles.css rel=stylesheet>
</head>
<body>
    <header class=glitch-zone>
        <nav class=navbar role=navigation aria-label="Main Navigation">
            <div class=navbar_left>
                <a href=/ class=h-card rel=me>
                    <strong>
                        Adler Medrado
                        <span class=cursor-blink>|</span>
                    </strong>
                </a>
            </div>
            <div class="navbar_right navbar_right_animated">
                <a href=/posts>posts</a>
                <a href=/missives>missives</a>
                <a href=/now>what am i doing now</a>
                <a href=/uses>what am i using</a>
            </div>
        </nav>
    </header>
    <main>
        <article class=missive>
            <h1 class="text-4xl font-bold mb-4">What I’d Tell My 23-Year-Old Self</h1>
            <p class="text-sm text-gray-500 mb-6">26 Sep 2025</p>
            <div class=prose>
                <p>If I could whisper to my 23-year-old self, I’d tell him this:</p>
                <ul>
                    <li>Stop wasting time worrying about what people think.</li>
                    <li>Pour your energy into building, into creating, into making something that’s yours.</li>
                    <li>And never forget: everything is impermanent — every victory, every failure, every storm.</li>
                </ul>
                <p>That truth alone is enough to keep you moving forward.</p>
            </div>
        </article>
        <div class=post-tags>
            <p>
                <strong>Tags:</strong>
                <a href=/tags/thoughts>thoughts</a>
            </p>
        </div>
    </main>
    <footer class=glitch-zone role=contentinfo>
        <div class=footer-content>
            <div class=copyright>
                <p>
                    <small>&copy; 1996-2025 Adler Medrado</small>
                </p>
            </div>
            <div class=gpg_signed_info>
                <p>
                    All pages on this website are PGP signed.
                    Import my 
                    <a href=/pub-key.asc aria-label="Download my PGP public key">public key</a>
                     and check with 
                    <em>curl https://adlermedrado.com.br/missives/what-id-tell-my-23-year-old-self/ | gpg --verify</em>
                </p>
                <p>
                    <em>Privacy policy: this website employs no tracking.</em>
                </p>
                <p>
                    <span class=badge-a-plus>
                        <a href="https://developer.mozilla.org/en-US/observatory/analyze?host=adlermedrado.com.br" aria-label="Mozilla Observatory Security Rating: A+">A+</a>
                    </span>
                    <span class=badge-description>Mozilla Observatory Security Rating</span>
                </p>
            </div>
        </div>
    </footer>
    <script>
    (function() {
        function c() {
            var b = a.contentDocument || a.contentWindow.document;
            if (b) {
                var d = b.createElement('script');
                d.innerHTML = "window.__CF$cv$params={r:'9a31943f6eaad8cb',t:'MTc2MzkxMDQ3Ng=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";
                b.getElementsByTagName('head')[0].appendChild(d)
            }
        }
        if (document.body) {
            var a = document.createElement('iframe');
            a.height = 1;
            a.width = 1;
            a.style.position = 'absolute';
            a.style.top = 0;
            a.style.left = 0;
            a.style.border = 'none';
            a.style.visibility = 'hidden';
            document.body.appendChild(a);
            if ('loading' !== document.readyState)
                c();
            else if (window.addEventListener)
                document.addEventListener('DOMContentLoaded', c);
            else {
                var e = document.onreadystatechange || function() {};
                document.onreadystatechange = function(b) {
                    e(b);
                    'loading' !== document.readyState && (document.onreadystatechange = e, c())
                }
            }
        }
    })();
    </script>
</body>
</html>
<!--
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEB9cP28xEbBnKQwLObV8aePHcNh0FAmjpMJEACgkQbV8aePHc
Nh114BAAlkjwHZgFP7b7xUr++nhvxslYyb4SEzpWOzWaf1pd1UnwK9g3dBgImdoq
hrBC0yUuGqyCu8ZflghIF2mEVex5uHBCB5SFeQyPqfLA9erFEAPoWQ3b6gcKNiKM
wHwPDNEbgNxjKfoxfHcL6qrzpBjm//EtzXBtgC0IV1HTXOv0CG2s2AiEtmFj2kHO
LlrlMnT0IiwfUfDpL1Va1/AAc3bLsAQJgQVNKkOueoE08OtvnJ2lsz7PhqsgREnF
eorexF2SsHRhueXtet892ICVJuWrZtdN401YhqhLWu8oL6ORrMuQv4ecHRPuk08k
lrZA5atOssG02ghKLd0ITC65R6rEe/Jk3u6oRXYinRKUHvtpFgSQcgVqzU0kbnFF
0a4v6uGkZN5fFTkQO7Ua0483Iv2B+w7B1soFUN034S8ASfOBZXxDdNpyq8vtfk2y
N2bYf5+u/HXn/lNqZsBrS1vY40HoogEch+oO4Im4nsar8znXw3HxiYUM0Th+oiTR
TTWa4NHITlvBOcnmH49mxHSc99vYu0/bSKm8qY8PiZiGXq+u+36X4/1W/A+oXACn
Ao9G0Ljt9bXN7/QGcrb8BYiC+1rgmcMOrGmx+dtbwzfJhkITn6QjykcKFRg+PEIO
Kkv3c6C17+Pz6LIPQe6I//V3LYSvUiMY8lGLuM/C/nvD5QPfMlQ=
=1D7N
-----END PGP SIGNATURE-----
-->

Sabe aquela sensação de que algo não está certo? Pois é, ter a assinatura embutida nos meus arquivos HTML sempre me incomodou um pouco. Apesar de ser super prático validar a assinatura com um comando simples, tipo curl https://adlermedrado.com.br/missives/what-id-tell-my-23-year-old-self/ | gpg —verify, a ideia de ter a assinatura “colada” no arquivo original me incomodava. Parecia que o arquivo não era mais o original, né?

How to verify my site signatures

Update on the GPG Signing of My Website

I don’t remember exactly when I started, but for at least two years I’ve been signing the HTML pages on my website with GPG. I do this as a way to practice sovereignty, authenticity, and to promote tools that help protect privacy.

At first, I kept the GPG signature embedded directly in the HTML content, for example:

<!--
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

- -->
<!doctype html>
<html lang=en>
<head>
    <meta charset=utf-8>
    <meta http-equiv=X-UA-Compatible content="IE=edge">
    <meta name=viewport content="width=device-width,initial-scale=1">
    <meta property="og:title" content="What I’d Tell My 23-Year-Old Self">
    <meta property="og:description" content="If I could whisper to my 23-year-old self, I’d tell him this:

    Stop wasting time worrying about what people think.
    Pour your energy into building, into creating, into making something that’s yours.
    And never forget: everything is impermanent — every victory, every failure, every storm.

    That truth alone is enough to keep you moving forward.">
    <meta property="og:url" content="https://adlermedrado.com.br/missives/what-id-tell-my-23-year-old-self/">
    <meta property="og:site_name" content="Adler Medrado's corner of the web">
    <meta property="og:type" content="article">
    <meta property="og:image" content="/images/default-og-image.png">
    <meta name=twitter:card content="summary_large_image">
    <meta name=twitter:title content="What I’d Tell My 23-Year-Old Self">
    <meta name=twitter:description content="If I could whisper to my 23-year-old self, I’d tell him this:

    Stop wasting time worrying about what people think.
    Pour your energy into building, into creating, into making something that’s yours.
    And never forget: everything is impermanent — every victory, every failure, every storm.

    That truth alone is enough to keep you moving forward.">
    <meta name=twitter:image content="/images/default-og-image.png">
    <title>What I’d Tell My 23-Year-Old Self</title>
    <meta name=description content="If I could whisper to my 23-year-old self, I’d tell him this:

    Stop wasting time worrying about what people think.
    Pour your energy into building, into creating, into making something that’s yours.
    And never forget: everything is impermanent — every victory, every failure, every storm.

    That truth alone is enough to keep you moving forward.">
    <link rel=author href=/humans.txt>
    <link rel=icon type=image/png href=/images/favicon.png>
    <link rel=canonical href=https://adlermedrado.com.br/missives/what-id-tell-my-23-year-old-self/>
    <link href=/css/styles.css rel=stylesheet>
</head>
<body>
    <header class=glitch-zone>
        <nav class=navbar role=navigation aria-label="Main Navigation">
            <div class=navbar_left>
                <a href=/ class=h-card rel=me>
                    <strong>
                        Adler Medrado
                        <span class=cursor-blink>|</span>
                    </strong>
                </a>
            </div>
            <div class="navbar_right navbar_right_animated">
                <a href=/posts>posts</a>
                <a href=/missives>missives</a>
                <a href=/now>what am i doing now</a>
                <a href=/uses>what am i using</a>
            </div>
        </nav>
    </header>
    <main>
        <article class=missive>
            <h1 class="text-4xl font-bold mb-4">What I’d Tell My 23-Year-Old Self</h1>
            <p class="text-sm text-gray-500 mb-6">26 Sep 2025</p>
            <div class=prose>
                <p>If I could whisper to my 23-year-old self, I’d tell him this:</p>
                <ul>
                    <li>Stop wasting time worrying about what people think.</li>
                    <li>Pour your energy into building, into creating, into making something that’s yours.</li>
                    <li>And never forget: everything is impermanent — every victory, every failure, every storm.</li>
                </ul>
                <p>That truth alone is enough to keep you moving forward.</p>
            </div>
        </article>
        <div class=post-tags>
            <p>
                <strong>Tags:</strong>
                <a href=/tags/thoughts>thoughts</a>
            </p>
        </div>
    </main>
    <footer class=glitch-zone role=contentinfo>
        <div class=footer-content>
            <div class=copyright>
                <p>
                    <small>&copy; 1996-2025 Adler Medrado</small>
                </p>
            </div>
            <div class=gpg_signed_info>
                <p>
                    All pages on this website are PGP signed.
                    Import my 
                    <a href=/pub-key.asc aria-label="Download my PGP public key">public key</a>
                     and check with 
                    <em>curl https://adlermedrado.com.br/missives/what-id-tell-my-23-year-old-self/ | gpg --verify</em>
                </p>
                <p>
                    <em>Privacy policy: this website employs no tracking.</em>
                </p>
                <p>
                    <span class=badge-a-plus>
                        <a href="https://developer.mozilla.org/en-US/observatory/analyze?host=adlermedrado.com.br" aria-label="Mozilla Observatory Security Rating: A+">A+</a>
                    </span>
                    <span class=badge-description>Mozilla Observatory Security Rating</span>
                </p>
            </div>
        </div>
    </footer>
    <script>
    (function() {
        function c() {
            var b = a.contentDocument || a.contentWindow.document;
            if (b) {
                var d = b.createElement('script');
                d.innerHTML = "window.__CF$cv$params={r:'9a31943f6eaad8cb',t:'MTc2MzkxMDQ3Ng=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";
                b.getElementsByTagName('head')[0].appendChild(d)
            }
        }
        if (document.body) {
            var a = document.createElement('iframe');
            a.height = 1;
            a.width = 1;
            a.style.position = 'absolute';
            a.style.top = 0;
            a.style.left = 0;
            a.style.border = 'none';
            a.style.visibility = 'hidden';
            document.body.appendChild(a);
            if ('loading' !== document.readyState)
                c();
            else if (window.addEventListener)
                document.addEventListener('DOMContentLoaded', c);
            else {
                var e = document.onreadystatechange || function() {};
                document.onreadystatechange = function(b) {
                    e(b);
                    'loading' !== document.readyState && (document.onreadystatechange = e, c())
                }
            }
        }
    })();
    </script>
</body>
</html>
<!--
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEB9cP28xEbBnKQwLObV8aePHcNh0FAmjpMJEACgkQbV8aePHc
Nh114BAAlkjwHZgFP7b7xUr++nhvxslYyb4SEzpWOzWaf1pd1UnwK9g3dBgImdoq
hrBC0yUuGqyCu8ZflghIF2mEVex5uHBCB5SFeQyPqfLA9erFEAPoWQ3b6gcKNiKM
wHwPDNEbgNxjKfoxfHcL6qrzpBjm//EtzXBtgC0IV1HTXOv0CG2s2AiEtmFj2kHO
LlrlMnT0IiwfUfDpL1Va1/AAc3bLsAQJgQVNKkOueoE08OtvnJ2lsz7PhqsgREnF
eorexF2SsHRhueXtet892ICVJuWrZtdN401YhqhLWu8oL6ORrMuQv4ecHRPuk08k
lrZA5atOssG02ghKLd0ITC65R6rEe/Jk3u6oRXYinRKUHvtpFgSQcgVqzU0kbnFF
0a4v6uGkZN5fFTkQO7Ua0483Iv2B+w7B1soFUN034S8ASfOBZXxDdNpyq8vtfk2y
N2bYf5+u/HXn/lNqZsBrS1vY40HoogEch+oO4Im4nsar8znXw3HxiYUM0Th+oiTR
TTWa4NHITlvBOcnmH49mxHSc99vYu0/bSKm8qY8PiZiGXq+u+36X4/1W/A+oXACn
Ao9G0Ljt9bXN7/QGcrb8BYiC+1rgmcMOrGmx+dtbwzfJhkITn6QjykcKFRg+PEIO
Kkv3c6C17+Pz6LIPQe6I//V3LYSvUiMY8lGLuM/C/nvD5QPfMlQ=
=1D7N
-----END PGP SIGNATURE-----
-->

You know that feeling when something just doesn’t sit right? Yeah, having the GPG signature embedded inside my HTML files always bothered me a little. Sure, it was super convenient to validate everything with a simple command like curl https://adlermedrado.com.br/missives/what-id-tell-my-23-year-old-self/ | gpg --verify, but the idea of having the signature “glued” to the original file just felt wrong. It was like the file wasn’t really the original anymore, you know?

Security isn’t a feature. It’s a consequence

People talk about security like it’s a product you install or a checkbox you tick off before launch. But that mindset is exactly why so many systems fail. Security isn’t a module. It’s not a team. It’s not something you slap on later. It’s a consequence — of how you think when you build.

Most software is a prototype that accidentally went live. Security gets added later. If it gets added at all. Usually after something breaks or someone screams.

Say Cheese: Catch Curious Eyes on Your Mac with a Snapshot

Ever worried someone might peek at your MacBook when you’re not around?

Last Friday, I built a simple, effective, and open-source solution to deal with that — and I called it Say Cheese.

Here’s the idea: if someone opens your Mac’s lid without authenticating via Touch ID, a photo is instantly taken and sent to your iPhone through iMessage. You get a live snapshot of the intruder — no fuss.

Say Cheese: Proteja Seu Mac de Curiosos com Uma Foto na Hora do Acesso

Já pensou alguém abrindo seu MacBook quando você não tá por perto?

Na sexta-feira criei uma solução simples, eficaz e de código aberto pra lidar com isso — e batizei de Say Cheese.

A ideia é a seguinte: se alguém abrir a tampa do seu Mac sem autenticar com Touch ID, uma foto é tirada na hora e enviada direto pro seu iPhone, via iMessage. Você recebe a cara do curioso em tempo real. Simples assim.

Update: Análise de emails (.eml) com FraudTalon

O FraudTalon deu mais um passo importante.

Mesmo com pouco tempo livre na semana, sigo comprometido em manter o FraudTalon avançando e publicando updates regulares.

A partir de hoje, é possível fazer o upload de arquivos .eml diretamente pela interface, e o sistema realiza uma análise completa combinando heurísticas de segurança de e-mails com inteligência artificial.

fraudtalon-banner

O pipeline está assim:

  • Parse automático do .eml, com extração dos headers, remetente, destinatário, assunto e corpo
  • Avaliação heurística com sinais como:
    • Mismatch entre From, Reply-To e Return-Path
    • Falhas de autenticação (DKIM, SPF, DMARC)
    • Recebimento por servidores desconhecidos
  • Análise por IA (via OpenAI) levando em conta todo o conteúdo textual
  • Score consolidado com os sinais suspeitos encontrados

Essa atualização transforma o FraudTalon em uma ferramenta muito mais útil para análise de e-mails suspeitos, como golpes de Pix, phishing, ou promessas falsas de investimento.

Update: Email (.eml) Analysis with FraudTalon

FraudTalon just took another important step.

I’m only able to work on FraudTalon a few hours per week, but I’m committed to making steady progress and sharing weekly updates.0

Starting today, you can upload .eml files directly through the interface, and the system will run a complete analysis using a combination of email security heuristics and artificial intelligence.

fraudtalon-banner

The pipeline now works like this:

  • Automatic .eml parsing with extraction of headers, sender, recipient, subject, and body
  • Heuristic evaluation with signals such as:
    • Mismatch between From, Reply-To, and Return-Path
    • Authentication failures (DKIM, SPF, DMARC)
    • Relaying through unknown servers
  • AI analysis (via OpenAI) that takes into account the full textual content
  • Final score with a breakdown of suspicious indicators

This update makes FraudTalon a much more powerful tool for analyzing suspicious emails like phishing, Pix scams, or fake investment offers.

Combatendo fraudes online com FraudTalon

Depois de receber tantas mensagens dos meus pais, esposa, irmã e amigos perguntando se certos e-mails ou anúncios que viram nas redes sociais eram legítimos, decidi criar uma ferramenta para ajudar a identificar fraudes, golpes e tentativas de phishing.

Foi assim que nasceu o FraudTalon

Atualmente ele está na versão MVP 0.0.1 — funcionalidades básicas, heurísticas simples (comecei com NLP mas deixei de lado — por enquanto, não é necessário) e um único LLM baseado em nuvem. O objetivo neste estágio é validar a ideia.

Fighting online fraud with FraudTalon

After getting so many messages from my parents, wife, sister, and friends asking if emails or ads they saw on social media were legit, I decided to build a tool to help identify fraud, scams, and phishing attempts.

That’s how FraudTalon was born.

It’s currently in MVP version 0.0.1 — basic functionality, simple heuristics (I started with NLP but dropped it — not needed for now), and a single cloud-based LLM. The goal at this stage is to validate the idea.

Building My Own Sovereign RAG for Secure Code Analysis

Building My Own Sovereign RAG for Secure Code Analysis

Lately, I’ve been taking a closer look at some code analysis tools that claim to detect security vulnerabilities in software projects. The idea itself is solid. I got one of these tools recommended to me and decided to dig deeper to see what’s really behind these solutions.

Pretty quickly I noticed a pattern: these platforms are far from cheap. Some offer limited free plans, but we all know how this game works. When something that good is offered for “free”, the real price usually comes from somewhere else — data collection, vendor lock-in, black-box models processing your code in someone else’s cloud. And since I’ve been deeply studying AI lately, especially Retrieval-Augmented Generation (RAG), the question came naturally: why not build my own pipeline, fully local, sovereign, using open-source tools, running on my own machine, and depending on no one?

Como construí meu próprio RAG soberano para análise de segurança de código

Construindo meu próprio RAG soberano para análise de segurança de código

Nos últimos tempos, comecei a olhar com mais atenção para algumas ferramentas de análise de código que prometem identificar falhas de segurança em projetos. A ideia é boa. Recebi uma dessas ferramentas como sugestão e fui atrás para entender melhor o que havia por trás da proposta.

Logo de cara percebi um padrão: os preços dessas plataformas não são exatamente convidativos. Algumas até oferecem planos gratuitos limitados, mas a gente sabe como funciona o jogo. Quando algo muito bom aparece “de graça”, o custo real costuma vir de outro lugar. Coleta de dados, lock-in na plataforma, modelos black-box processando seu código na nuvem de terceiros. E como hoje eu venho estudando bastante IA e, em especial, o tema dos RAGs (Retrieval-Augmented Generation), a pergunta veio automática: por que não montar o meu próprio pipeline, 100% local, soberano, usando ferramentas open-source, rodando direto na minha máquina, sem depender de ninguém?

MDN Report A+

MDN A+ badge

Ran my site through MDN’s security scanner and kept tweaking until I hit 120/100 (A+).

Checked the scan history and the very first one, back in 2018, scored 20/100 (F).

Always improving.

Real-time Deepfakes: what if "seeing is believing" no longer means anything?

An open-source project called Deep-Live-Cam is gaining traction on GitHub — and for good reason.

With just a single still image, it can mimic anyone’s face in a live video call. In real-time. Running locally. No cloud required.

The implication is clear: you can no longer trust a video call at face value.

So here’s the question: how do we verify identity in a world where faces can be forged on demand?

Deepfakes em tempo real: e se "ver para crer" já não valer mais nada?

Um projeto open-source chamado Deep-Live-Cam está chamando atenção no GitHub. E com razão.

Com apenas uma imagem estática, ele consegue simular o rosto de qualquer pessoa em tempo real, dentro de uma chamada de vídeo. Tudo isso rodando localmente. Sem nuvem. Sem limites.

A consequência é direta: não dá mais pra confiar em uma chamada de vídeo.

E isso levanta a pergunta inevitável: como validamos a identidade num mundo onde rostos podem ser forjados ao vivo?

Por que você deveria começar a usar GPG agora

Por que você deveria começar a usar GPG agora

Se você ainda não utiliza GPG para assinar ou criptografar seus arquivos e mensagens, está na hora de repensar isso. Não é apenas sobre parecer um hacker de filme dos anos 90 — é sobre proteger sua comunicação e identidade digital em um mundo cada vez mais hostil.

🔐 O que é GPG?

GPG (GNU Privacy Guard) é uma implementação livre do padrão OpenPGP. Ele permite que você crie pares de chaves criptográficas para assinar digitalmente arquivos e mensagens, além de criptografá-los para garantir confidencialidade. É uma ferramenta essencial para quem leva a sério a segurança digital.

Why You Should Start Using GPG Now

Why You Should Start Using GPG Now

If you’re not using GPG to sign or encrypt your files and messages yet, it’s time to reconsider. It’s not just about looking like a 90s movie hacker — it’s about protecting your communication and digital identity in an increasingly hostile world.

🔐 What is GPG?

GPG (GNU Privacy Guard) is a free implementation of the OpenPGP standard. It allows you to create cryptographic key pairs to digitally sign files and messages, as well as encrypt them to ensure confidentiality. It’s an essential tool for anyone serious about digital security.

Shadowdata Updates

Yesterday, I published a blog post introducing my new open-source project, ShadowData.

This post is just to inform anyone interested that I have made some updates today.

New Features Added to the Project:

  • Email address anonymization
  • Phone number anonymization
  • Symmetric cryptography for encryption and decryption
  • Minor improvements to tests and code quality

You can look the code at the Github repository.

See you.

Shadowdata Sensitive Data Handler Python Library

I am deeply concerned about how to handle sensitive data in the projects I work on. Nowadays, there are laws in various countries addressing this issue, and the topic becomes increasingly important as time goes on.

Therefore, I decided to create a Python library that can help me deal with scenarios where it is necessary to process data to prevent any individual from being identified if the information is accessed. The library also handles data transformations, encryption, and the detection of sensitive personal data.

Sudo com Touch ID no macOS

Configurar o sudo para usar o Touch ID no macOS Sonoma em apenas alguns passos é muito fácil.

Localize o arquivo /etc/pam.d/sudo_local.template e faça uma cópia conforme o exemplo abaixo:

sudo cp /etc/pam.d/sudo_local.template /etc/pam.d/sudo_local

Em seguida, edite o arquivo e remova o caractere # do início da linha 3, ele deve ficar assim:

# sudo_local: arquivo de configuração local que sobrevive a atualizações do sistema e é incluído para sudo
# descomente a linha a seguir para habilitar o Touch ID para sudo
auth sufficient pam_tid.so

Passos detalhados para editar o arquivo

Para editar o arquivo, use um editor de texto como nano ou vim. Por exemplo, com o nano:

Sudo with Touch ID on macOS

Setting up sudo for use with Touch ID on macOS Sonoma in just a few steps is very easy.

Locate the file /etc/pam.d/sudo_local.template and make a copy as shown in the example below:

sudo cp /etc/pam.d/sudo_local.template /etc/pam.d/sudo_local

Then edit the file and remove the # character from the beginning of line 3, it should look like this:

# sudo_local: local config file which survives system update and is included for sudo
# uncomment following line to enable Touch ID for sudo
auth sufficient pam_tid.so

Detailed Steps to Edit the File

To edit the file, use a text editor like nano or vim. For example, with nano:

Assinando páginas HTML com GPG

Há alguns meses eu reformulei este site, eu estava usando wordpress e não estava muito feliz com isso, então decidi usar um gerador de páginas estáticas, nesse caso o Hugo.

No passado eu já utilizei o Pelican, o Jekyll e o Dangolino, este último era uma ferramenta criada por mim, mas que descontinuei depois de algum tempo. Se não me engano, há posts aqui falando sobre eles.

Por que assinar as páginas?

Eu vejo a criptografia como um mecanismo de defesa, acredito que as pessoas devem criptografar tudo, para tentar garantir segurança, privacidade e autenticidade, entre outras coisas.

Signing HTML Pages with GPG

A few months ago I rebuilt this site. I was using WordPress and wasn’t very happy with it, so I decided to use a static site generator, in this case Hugo.

In the past I’ve used Pelican, Jekyll and Dangolino, the last one being a tool I built myself but discontinued after a while. If I’m not mistaken, there are posts here talking about them.

Why sign the pages?

I see cryptography as a defense mechanism. I believe people should encrypt everything, to try to guarantee security, privacy and authenticity, among other things.

A Segurança Das Urnas Eletrônicas

Quem me conhece sabe que eu sempre desconfiei da segurança das urnas
eletrônicas brasileiras, um dos fatores que me levam a ter essa postura
é devido ao fato de o código das urnas ser fechado e não passar por
auditorias externas.

Outro motivo é que aqui no Brasil nada que o governo coloca as mãos
funciona direito, vide a saúde, educação, segurança, etc., então é de
se desconfiar que a única coisa que funciona bem seja a urna eletrônica,
algo tão vital para a manutenção da democracia.