HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
18F
identity-idp
Ruby2017–2025
18F / identity-idp

identity-idp

Login.gov Core App: Identity Provider (IdP)

16Distinct people
33Mentions
0Explicit recommenders
596GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Login.gov Core App: Identity Provider (IdP)

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 8–Nov 15 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/15/2026, 10:02:05 AM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year33 dated mentions

Observed mentions: 2017-09-08 19:20:27 UTC to 2025-03-02 16:32:17 UTC.

02468102017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 7 mentions; 0 submissions, 7 comments20172018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 7 mentions; 0 submissions, 7 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 10 mentions; 0 submissions, 10 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments20212022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2025

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC707
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC101
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC707
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC10010
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC202
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC202
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC101
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC101
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC202

What Hacker News says

7 sources
EDIT: OK, I think I see what's wrong with this analysis: https://github.com/18F/identity-idp/blob/master/spec/service.... They do include Z1 in the data they pass to KMS decrypt. This is because they have XORed the ciphertext with Z1 - so now in order to recover the initial ciphertext back (i.e. the cipher text you can decrypt with KMS to get R back), you need to XOR with Z1 again. So even if you get D from the database, you can't decrypt it unless you have Z1, and if you were trying to brute-force it, you would need to call KMS for every attempt with the Z1 for this attempt. Original comment: I am not any kind of crypto expert. But I agree with you. I think they should be XORing with "AssignedSecret" (not "EncryptedAssignedSecret"). Then in order to compare password hashes you would need to decrypt the "EncryptedAssignedSecret" using KMS
Read the rest
. (using the terminology in the description of the algorithm here: https://github.com/18F/identity-idp/blob/master/docs/encrypt...) (EDIT: you actually cover this approach in the GH issue, and point out a problem with it). I think there is another approach like what the OP proposed where they should be using some portion of the scrypt hash (either Z1 or Z2 or just the whole thing) as part of the encryption context passed to KMS. But this seems a little more complicated to me. (EDIT: You also mention this as a possible solution in the GH issue). I think there's also an approach using the GenerateDataKey API : http://docs.aws.amazon.com/kms/latest/APIReference/API_Gener... Where you get the key and the key's cipher text back from KMS and store that, and then you have to use KMS to decrypt whatever you encrypted with the key.
In Login.gov encryption is badly designed
I opened an issue on their bug tracker a couple days ago because I had more fundamental questions about how their algorithm was designed. HN comment: https://news.ycombinator.com/item?id=15204989 Github Issue: https://github.com/18F/identity-idp/issues/1665 Now I may be misunderstanding their implementation, but it seems to me actually worse than "this isn't FIPS 140". I take no issue with their use of scrypt at all. The complaints in this Gist actually seem to miss the mark to me. The problem isn't scrypt, or storing a hash. The real problem is storing d which, seems to me, defeats the purpose of using an HSM in the first place! Again, with the disclaimer that I'm not 100% certain that's what they're doing, it's just what the documentation says, and what it seems like is happening from reading the Ruby code. I don't develop in Ruby, but
Read the rest
while the language is fairly easy to read, with all their variables named 'encryption_code', 'encryption_key', 'encrypted_key', 'encrypted_code', etc. it's easy to get lost. EDIT: Can someone please co-validate my analysis please? Or please tell me what I got wrong! From what I can see, the design is obviously broken. I don't consider myself qualified to find flaws in other people's crypto so, when I find obvious flaws in what should be well designed crypto I get a little freaked out.
In Login.gov encryption is badly designed
A total nit pick, but why do people have such a hard time consistently naming something as simple as a boolean variable? If we remember that naming is one of the hardest things in software engineering, why don't we put more thought into it? From the documentation in the README: https://github.com/18F/identity-idp disable_email_sending: ‘true’ enable_load_testing_mode: ‘true’ telephony_disabled: ‘true’ Multiple directions, multiple naming conventions, strings?!?!?. Just seems like a recipe for failure. I feel like this would be more clear: load_testing_mode: true send_email: false telephony: false When you write your conditionals, it makes it so much easier to read: if !disable_email_sending do_send_email vs. if send_email do_send_email Here is the line in actual use... https://github.com/18F/identity-idp/blob/
Read the rest
df549cf9a1fc2c21e3e... I'd personally rather have the positive condition first as it is easier for me to follow logically in my head.
In Government launches login.gov to simplify access to public services
Login Spec Here: https://github.com/18F/identity-idp/blob/master/docs/encrypt... Many aspects of this make no sense to me... so IF this is actually what they are doing... hash(user, password) { salt = CS-PRNG(160bit) s = scrypt(salt, password) z1 = s[0:32] z2 = s[32:64] R = CS-PRNG(256bit) d = HSM(R) XOR (pad_right(z1, 0x00, 32 bytes)) cek = SHA256(z2 || d) hash = SHA256(cek) save_record(user, d, salt, hash) } First and foremost, if the HSM operation is to have any meaning, it needs to be in the critical path for encrypting / decrypting data and possibly also calculating the password hash. If you don't need to go through the HSM to perform a decrypt or a hash validation, then obviously the HSM isn't actually securing anything! All it becomes is a source of entropy into the key derivation, but that
Read the rest
's more likely to harm than help. From their own specification; "It is important to note that the HSM factor strengthens the model in a way different than the other two factors, which rely on keeping them secret. Because the HSM is tied to a physical object, brute force attacks on our database would need to happen in proximity to the HSM, i.e., within our AWS environment, which greatly reduces the attack surface. A bad actor with a copy of the database cannot apply their own computing power to brute force cracking of passwords." But to be clear, if you have 'd', 'salt', and 'hash', you can brute force attack passwords as; s = scrypt(salt, password) h = SHA256(SHA256(s[32:64] || d)) h =? hash Now, if they were not storing 'd' in the user record, you might think to store what they call 'R' in the user record. Then you would have to go through the HSM as part of each login to derive the correct 'd' and 'cek' which is how it's supposed to work. But even that design is still not good enough. You don't want to allow an attacker to pull 'R' from your database, send it through the HSM just once, and then be able to start brute forcing the password forever from there on out. If you're going to pay for an HSM, and your going to call it for each password verification, then you better make sure an attacker is also required to call the HSM for each attempt at verifying a password. Which means you send your password hash (or something derived from it) through the HSM, not just a random 'R'! Next, besides all of that, the design is horrific for end users. PII is encrypted with 'cek' above. That means if you lose your password, you lose your PII. Which means starting basically a new account from scratch! I can't endorse the idea that a password reset from an end user will effectively wipe out their account information and make them start over. The vast majority of users will be logging into this service infrequently. Combine this with a typically user hostile password policy, and the result is that a large percentage of users will be resetting their password every time they need to login. With this design, that means they have to start over with validation through a third party... and guess who that third party is? Companies like Equifax now responsible for the single largest PII breach in American history. Now they've also added something like a recovery key which the user is supposed to print out and save at the moment they create their account, and that key is used to separately encrypt all the PII. So if the user forgets their password but can find this magic piece of paper, they can enter this key (that'll be fun) as part of the password reset process and reset their password without effectively wiping their account. To think "Average Users" will succeed in doing this belies reality. But wait... where is this magic key being saved on login.gov servers? If it was a private key they give to the user and they just keep the public key on their side that could work, but it's actually an uppercase 16 character alphanumeric token... 5.17 * 16 = 82 bits. Let's hope that's not literally the encryption key, but the alternative -- it's a token used to lookup the key in their database -- would completely defeat the purpose of encrypting the PII with a PBK in the first place?! And, even if it was the literal encryption key, when you change or update your PII, if they don't also keep it on their side, how would they update their secondary encrypted PII record?
In Government launches login.gov to simplify access to public services
In case you are wondering how it handles password encryption and storage, it appears to use a custom password hash based on SHA256 and scrypt: https://github.com/18F/identity-idp/blob/980c2aa26397f530673... Passwords appear to be stored in the users table in the "encrypted_password" column, and it does not appear that any database-based security is used. This is one RCE/SQLI vulnerability away from exposing the password hashes for all users. To be fair, that's probably true of most sites that store password hashes, but I would have expected better from 18F.
In Government launches login.gov to simplify access to public services

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.