You Should be Using Rootless Containers

Posted by
on under

The other day a serious vulnerability was disclosed in one of the newer Linux distributions (the one led by the racist, so it isn't getting a mention here). The issue was interesting because it was caused by a non-standard Docker configuration that their installer applied by default, without alerting users that this configuration was creating a security risk. The end result was that any process running on these systems had the ability to elevate itself to root, without password, sudo or any prompts to the user.

While this incident did not affect me, it served as a reminder that it is difficult to set up Docker in a way that is secure. If you are interested in understanding what the issues with Docker are and what can be done to address them, then you are in the right place.

Forgejo hack #2: Integration with Read The Docs

Posted by
on under

In this second Forgejo Hack installment I'll tell you how to connect a git repository that lives in your self-hosted Forgejo instance to Read the Docs, so that commits to the repository automatically trigger documentation builds, exactly like it works with GitHub.

Forgejo hack #1: How to set a starting issue and pull request number

Posted by
on under

I'm currently working on migrating my open source projects from GitHub to a self-hosted Forgejo instance. As part of this effort I often end up looking through the Forgejo source code to figure out if there are hidden ways to configure certain things to my liking when I can't do it on the administration UI. I thought I'd start putting my discoveries in writing here, in case they can help others. So here goes the first one.

One of the aspects of the migration that is tricky is how to transition issues and pull requests. What makes the most sense to me is to only use Forgejo to track issues and pull requests going forward, leaving all the issues and pull requests created up to the migration point on GitHub. Of course whether this is a good or bad idea is debatable, but considering all the options I have decided that this is the solution that is going to inflict the least pain on me.

The one problem with this approach is that I would end up having duplicate issue numbers, because Forgejo would start creating issues and pull requests all the way back from #1, and all those low numbers have been used on the GitHub side. So I wanted to hack my Forgejo instance so that issues start from, say, 10000. That way when anyone references an issue by its number I would know that numbers below 10000 are on GitHub and only those above are on my own instance.

I Am Not a Reverse Centaur

Posted by
on under

About a year ago I wrote on this blog about how coding with LLMs would not work for me, even if there were no ethical or environmental concerns preventing me to use them. I'm not going to repeat the arguments I made that time because my views on the subject haven' t changed. What has changed, however, is that the number of contributions I receive on my open source projects has gone up, and nearly all are now made with LLMs.

The other day I had a very depressing thought regarding this. All these people who submit drive-by pull requests to my projects are pushing me to spend more and more of my time reviewing and merging code that was extruded by machines. Cory Doctorow refers to people that perform this function as reverse centaurs. He calls these "frail and vulnerable people being puppeteered by uncaring, relentless machines." Ouch!

Am I a reverse centaur now? Is my new purpose as a seasoned software engineer and open source developer to spend my days reviewing LLM code, in spite of having decided that I do not need nor want this technology myself? As you can guess from the title, I'm never going to become a reverse centaur. Let me tell you how I resist the forces that want me to be one.

SQLAlchemy 2 In Practice - Solutions to the Exercises

Posted by
on under

To conclude with my SQLAlchemy 2 in Practice series, this article contains the solutions to all the exercises. If you'd like to support my work, I encourage you to buy this book, either directly from my store or on Amazon. Thank you!

SQLAlchemy 2 In Practice - Chapter 8: SQLAlchemy and the Web

Posted by
on under

This is the eighth and final chapter of my SQLAlchemy 2 in Practice book. If you'd like to support my work, I encourage you to buy this book, either directly from my store or on Amazon. Thank you!

Whether you are building a traditional web application, or a web API that works alongside a web front end or smartphone app, SQLAlchemy is one of the best choices to add database support to a Python web server. In this chapter two example integrations with Flask and FastAPI will be demonstrated. These are two of the most popular Python web frameworks and should serve as examples even if you use another web framework.

SQLAlchemy 2 In Practice - Chapter 7: Asynchronous SQLAlchemy

Posted by
on under

This is the seventh chapter of my SQLAlchemy 2 in Practice book. If you'd like to support my work, I encourage you to buy this book, either directly from my store or on Amazon. Thank you!

Starting with release 1.4, SQLAlchemy includes support for asynchronous programming with the asyncio package, for both the Core and ORM modules. This is an exciting improvement that brings the power of SQLAlchemy to modern applications such as those written with the FastAPI web framework.

How Bitwarden Encrypts and Decrypts Secrets

Posted by
on under

As part of my efforts in reducing my dependency on Big Tech, I have been researching how to self-host my password manager. One solution that looks very promising is Vaultwarden, an open source clone of the Bitwarden cloud server. An interesting aspect of this server is that it stores all the secrets in a standard SQLite database, so in addition to having the self-hosted password server I could keep a backup copy of the database on my machine and query it directly. But of course, the secrets are encrypted in this database, so they are useless unless I learn how to decrypt them, similar to how the Bitwarden clients do it.

Speaking of the Bitwarden clients, while I was writing this article it came out that the official Bitwarden CLI client was compromised in a supply chain attack. This is a tool that I personally use and have on all my computers, so this feels like a wake up call to me. Luckily I did not install the compromised version myself, but I think there is an argument to be made about rolling your own secret management client instead of relying on the one all the hackers are after!

In this article I'll share how the encryption of secrets works in Bitwarden and its Vaultwarden clone. I'll also include working Python code, in case you want to tinker with this and like myself, would be interested in building your own tooling to keep your secrets safe.

SQLAlchemy 2 In Practice - Chapter 6: A Page Analytics Solution

Posted by
on under

This is the sixth chapter of my SQLAlchemy 2 in Practice book. If you'd like to support my work, I encourage you to buy this book, either directly from my store or on Amazon. Thank you!

The goal of this chapter is to use the concepts you have learned to build a web traffic analytics solution. This will serve as reinforcement of the techniques demonstrated in previous chapters as well as an example of a more complex and realistic database design.

SQLAlchemy 2 In Practice - Chapter 5 - Advanced Many-To-Many Relationships

Posted by
on under

This is the fifth chapter of my SQLAlchemy 2 in Practice book. If you'd like to support my work, I encourage you to buy this book, either directly from my store or on Amazon. Thank you!

You have now learned the design blocks used in relational databases. Sometimes, however, these building blocks have to be "tweaked" a bit to achieve a desired goal. This chapter is dedicated to exploring a very useful variation on the many-to-many relationship.