---
title: "About me • Gabriel Rosa"
description: "find out the techie stuff Im into, a bunch of pics, and the certificates that make me look legit. Its me in a nutshell, no fluff. Enjoy!"
canonical_url: "https://rosa.sh/about"
locale: en
meta:
  "og:description": "find out the techie stuff Im into, a bunch of pics, and the certificates that make me look legit. Its me in a nutshell, no fluff. Enjoy!"
  "og:image": "https://rosa.sh/_og/d/c_Simple.takumi%2Ctitle_About%2Bme%2Cdescription_~ZmluZCBvdXQgdGhlIHRlY2hpZSBzdHVmZiBJbSBpbnRvLCBhIGJ1bmNoIG9mIHBpY3MsIGFuZCB0aGUgY2VydGlmaWNhdGVzIHRoYXQgbWFrZSBtZSBsb29rIGxlZ2l0LiBJdHMgbWUgaW4gYSBudXRzaGVsbCwgbm8gZmx1ZmYuIEVuam95IQ%2Cp_Ii9hYm91dCI%2Cs_URV9_NBzZe8nH6fK.png"
  "og:image:height": "600"
  "og:image:type": image/png
  "og:image:width": "1200"
  "og:title": "About me • Gabriel Rosa"
  "twitter:image": "https://rosa.sh/_og/d/c_Simple.takumi%2Ctitle_About%2Bme%2Cdescription_~ZmluZCBvdXQgdGhlIHRlY2hpZSBzdHVmZiBJbSBpbnRvLCBhIGJ1bmNoIG9mIHBpY3MsIGFuZCB0aGUgY2VydGlmaWNhdGVzIHRoYXQgbWFrZSBtZSBsb29rIGxlZ2l0LiBJdHMgbWUgaW4gYSBudXRzaGVsbCwgbm8gZmx1ZmYuIEVuam95IQ%2Cp_Ii9hYm91dCI%2Cs_URV9_NBzZe8nH6fK.png"
---

> Index of every page on this site: [llms.txt](https://rosa.sh/llms.txt)

# About me

I'm a software engineer who also runs the servers my code ends up on. Since 2019 I've been at CBPF, the Brazilian Center for Physics Research, where I take care of most of what makes the institute work on the web side: the machines, the network services they depend on, and a good part of the apps people open every day.

I like owning the whole path of a request. I write the frontend in Nuxt and the backend in Go, put it in a container, ship it through GitLab CI, and I'm also the one who configured the nginx in front of it, the DNS that points to it, the LDAP it authenticates against and the backup that brings it back when something breaks. Knowing every layer makes debugging a lot less painful, and it keeps me honest about how much complexity I'm adding.

Outside of work I mostly build the tools I end up needing at work. LDAP Studio is a native macOS LDAP client I wrote in SwiftUI with a C core on top of libldap and OpenSSL, because the only decent option we had needed a Windows VM just to browse the directory. I also keep a few small open source packages, like nuxt-cap and my oxlint/oxfmt config, and this site.

## Experience

1. [**Brazilian Center for Physics Research**](https://cbpf.br)

   Software Engineer & DevOps

   2019 - present

   When I started, a lot of what the institute relied on was old. Apps in PHP 5 with no framework, servers on Debian and Ubuntu releases long past end of life, BIND 9 for DNS and OpenLDAP for accounts. A big part of my job over these years has been replacing all of that one piece at a time, without taking down the things people depend on.

   The servers I manage now run Rocky Linux with SELinux enforcing, virtualized on VMware and provisioned with Ansible. Every web host follows the same layout: nginx on the host with HTTP/2 and HTTP/3, apps in Docker Compose bound only to localhost, and all of the configuration (vhosts, compose files, certificates) versioned in Git. A push to that repo fires a webhook that reloads nginx or redeploys the container through cbpfdocker, a small CLI I wrote in Go for exactly that.

   I moved the DNS from BIND 9 to PowerDNS. There are four authoritative servers on a MySQL backend serving cbpf.br, rederio.br and a few other zones, all signed with DNSSEC and NSEC3, plus four PowerDNS Recursor boxes behind a round robin name for the internal network. The old BIND machines are being retired as the last zones move over.

   Accounts used to live in OpenLDAP. I migrated everything to 389 Directory Server, which is now a four node cluster with one writable primary and three read-only replicas, custom schemas for the attributes the institute needs, TLS on every node, hourly backups and exporters feeding Prometheus.

   On top of the directory I built the login everyone uses. The CBPF SSO is our own OpenID Connect provider, written in Go and Nuxt, with Redis sessions and a self-hosted proof of work captcha, no Keycloak involved. Next to it is ID CBPF, where accounts are actually created and managed. It writes straight to LDAP, handles groups and academic profiles like ORCID and Lattes, and every other app reads people's data from there instead of keeping its own copy.

   The project I've been deepest into lately is the rewrite of CBPF Index, the system that tracks the institute's scientific output: papers, theses, patents, software, projects and events. The original went live in 2004, written in PHP 5 with Smarty templates and a Yii admin panel added later, about 48 thousand lines of it. I read it file by file, wrote down every rule it had, and rebuilt it in Nuxt 4 and Go, with login through the SSO, people coming from LDAP and PDFs on S3.

   The migration was half the work. I wrote the scripts that move everything from MySQL in latin1 to MongoDB, match old users to LDAP accounts, merge more than 30 thousand external coauthors into a single list, move around 8 GB of PDFs and keep every old URL redirecting to its new page. I'm also adding a chat that answers questions about the whole public collection, running entirely on our own hardware: gpt-oss-120b and bge-m3 on Ollama across eight GPUs, Qdrant over more than 300 thousand chunks extracted from the PDFs (with OCR for the scanned ones), and tool calls into MongoDB so counts and author lists come back exact instead of guessed.

   Most of what we run is built in house on the same stack. Nuxt in front, Go behind, MongoDB, MySQL and Redis on a central database server, files on self-hosted S3 (we moved from MinIO to RustFS), errors going to a self-hosted Sentry compatible server, analytics in Umami and uptime in Uptime Kuma. To keep it consistent I maintain a project template and shared packages for Nuxt, Node and Go on our GitLab registry, so a new app already starts with auth, error tracking and deploy wired up.

   I run the institute's GitLab with shared runners, container and npm registries, and GitLab Pages. Recently I moved Pages off a subdomain of cbpf.br to its own domain, cbpf.page, so a user's site can't set cookies that reach the SSO or anything else under the main domain, and submitted it to the Public Suffix List.

   I also host the third party tools the teams use day to day, like Vaultwarden, Outline, Vikunja, OpenProject, OnlyOffice and Stirling PDF, and the backup service that covers everything. That one is a Go program I wrote that dumps DNS, MySQL, MongoDB, LDAP, S3 buckets and Docker volumes on a schedule and emails us when anything fails. Every host exposes node, container, nginx, database, LDAP and DNS metrics for monitoring, and I handle the TLS certificates for all of it.

   There's also a server for researchers and groups who keep their own WordPress or old PHP sites. Each site runs in its own container with the code mounted in the owner's home directory, so they can edit it over SSH while I take care of nginx, certificates and patching underneath.

   I also lead the web team. I split and follow up on tasks, review code, take part in hiring and help interns get comfortable with Linux, Git, Docker and the way we build things. Pretty much everything above is documented so anyone on the team can pick it up without having to ask me first.

```json
{"@context":"https://schema.org","@graph":[{"@id":"https://rosa.sh/#website","@type":"WebSite","description":"Software Engineer & DevOps","inLanguage":"en-US","name":"Gabriel Rosa","url":"https://rosa.sh/","publisher":{"@id":"https://rosa.sh/#identity"},"workTranslation":{"@id":"https://rosa.sh/pt#website"}},{"@id":"https://rosa.sh/about#webpage","description":"find out the techie stuff Im into, a bunch of pics, and the certificates that make me look legit. Its me in a nutshell, no fluff. Enjoy!","name":"About me","url":"https://rosa.sh/about","@type":["WebPage","AboutPage"],"isPartOf":{"@id":"https://rosa.sh/#website"}},{"@id":"https://rosa.sh/#identity","@type":"Person","name":"Gabriel Rosa","url":"https://rosa.sh","sameAs":["https://twitter.com/deth_gr"]}]}
```

## Sitemap

See the full [sitemap](https://rosa.sh/sitemap.md) for all pages.
