Recently I have started contributing to Kanidm: an identity management platform (IDM) written in Rust.
An identity management platform is used for users authentication and users administration. Examples of popular IDM options include Microsoft Active Directory and 389 Directory Server. Kanidm is a modern implementation of IDM that aims to be simple, secure and fast.
I first notice Kanidm on the GSoC website. I was looking for projects that are security-related and I want to learn a system-level programming language. So Kanidm seems like a perfect fit for me. Moreover, it is a relatively smaller project (for now) and easy to understand.
Through asking questions, reading the design doc and submitting PR, I begin to see the bigger picture of Kanidm. I learned a lot during this process, both technically and non-technically.
I will probably make a separate blog for each topic here:
- How to do Login / Authentication: The current most popular methods are: Password, MFA with TOTP, WebAuthn and OAuth.
- How to do secure Password Authentication: Although NIST recommend MFA be used whenever possible, there are still a lot of users with password-only login. To enhance password login security, we can use tricks like rate-limiting, storing password in database in non-reversible format, etc.
- Different kinds of One-Time Password (OTP): When and how to use HMAC-based One-time Password algorithm (HOTP) and Time-based One-time Password Algorithm (TOTP).
- How to generate random number securely: CSPRNG and PRNG.
- Cryptographic hash function: SHA-XXX vs bcrypt/PBKDF2/… (KDF), rainbow table attack.
- How to prevent attack: When designing a new workflow, we need to make sure that it is secure. For example, how using TOTP can alleviate replay attack.
- …And so much more!
Distributed System related:
- Replication: For now, Kanidm uses sqlite, i.e. each Kanidm instance has it’s own sqlite database. If we want to have a HA environment, we need to figure out a way to replicate data across multiple instances. Since Kanidm provides Availability and Partition, it only offers eventual consistency.
- Coordination between servers: For example, in Kanidm we lock account based on the # of failed login attempts. Since there is no central database, we must come up with a way to inform other instances of failed login attempts in near real-time.
One thing I learned is where to lookup security best practise. Mainly you should look at NIST, but you can also check out how Microsoft, Okta, Auth0, etc. implement their security features.
Besides, I also learned a lot on how to do open source development…
Let’s not forget the essence of Open Source is that it’s a place for PEOPLE to collaborate on free software. :) So one thing I learned about Open Source is how to work with others. In addition to the actual code, documentation, PR reviews, discussion with others (including dev and users) are equally important. Implementing a feature includes a lot of things outside of coding, for example: How to design a secure workflow such that there are no MITM attack? How should the users interact with the Kanidm?… All these things require discussion with your peers, and we must remain friendly and civil yet crictical.
Also, choosing a project that fits your interest is very important, but so is the community behind it. The best community is the one that is not toxic, supports new comers and responsive. The first two should be obvious, but the third might need some explaining. The availability of the maintainers is very important imo. When you look for a new project, you should check how and when the maintainers respond, and use that to determine what you should expect. I think it is a good sign if somebody respond to you in details and within say ~2 days.
So shoutout to @firstyear for being an great mentor and maintainer of Kanidm. I can say that he is a very friendly mentor who gives detailed and thoughtful response. I also recommend anyone who wants to learn Rust and code to contact people in @awesome-rust-mentor, who mentor people voluntarily. Seriously just go and drop them an email!
First impression on Rust
One thing I had to say is how good it is to program in Rust. With the powerful compiler and secure features (e.g. borrow checking), it gives developers a lot of confidence in their code. For a beginner, Rust offers a vibrant and supportive community with people eager to help. Most of the things are really well-documented, you can find everything from high-level programming features to how Rust code compiles to LLVM.
Compared to Kotlin, something that I used before, it allows programmers to code in a lower-level with finer control of resources, while maintaining a good developer experience! This has to be attributed to the great toolschain of Rust: cargo and the copmiler: rustc.
All in all, I really look forward to keep learning and coding more with Rust!