Keeping track of architectural-ish decisions in a sustainable way with Juan Saavedra
Published November 3, 2022
This video features Juan Saavedra at DjangoCon US 2019 in San Diego, California, USA.
DjangoCon 2019 - Building a multi factor SSO for a whole country with Django by Juan Saavedra
As a leading digital country and a D9 member, Uruguay decided to build its own world class multi factor auth service for its citizens. We will show how Django once again delivered on its promises in a complex scenario, enabling a fast and flexible development of a secure and reliable solution.
This talk was presented at: https://2019.djangocon.us/talks/building-a-multi-factor-sso-for-a-whole/
LINKS:
Follow Juan Saavedra 👇
On Twitter: https://twitter.com/elpaquete
Official homepage: https://www.octobot.io
Follow DjangCon US 👇
https://twitter.com/djangocon
Follow DEFNA 👇
https://twitter.com/defnado
https://www.defna.org/
Intro music: "This Is How We Quirk It" by Avocado Junkie.
Video production by Confreaks TV.
Captions by White Coat Captioning.
Uruguay built a national single sign-on platform for public services and selected private services, using the country’s electronic ID card, digital signatures, passwords, and other authentication factors to verify citizens at different assurance levels. Juan Saavedra explains how the team built the service with Django, Django REST Framework, React, Celery, and OpenID Connect, focusing on threat modeling, security by design, explicit permissions, least privilege, careful logging, throttling, and scalable deployment. The platform uses signed tokens to carry progress through variable, challenge-based authentication without storing a session in the database for every request, allowing requests to be handled by any backend instance. Saavedra’s main argument is that Django can support critical government infrastructure when teams understand the security model, avoid unsafe defaults, and treat availability and developer responsibility as part of security.
Summarised automatically from the transcript.
Automatically transcribed, so expect mistakes in names and technical terms.
Speaker 1: Thank you everybody for coming. It's my first DjangoCon. I'm pretty excited to be here. Got a wonderful event going on. Uh and the first thing to do is fix the title. I don't know how many people know what an SSO is. But that actually stands for a single sign-on. So before proceeding, just a quick heads up. We work we we mark this uh I mark this talk for everybody and in and it's true I I think that every everybody regardless of level can take uh uh insightful things from from our experience but some
Speaker 1: bits uh might be uh a bit in depth or a bit too security so don't worry We'll hope that by the end it it all holds up and and you can say I didn't lie. So um let's get started. Uh about me briefly, I'm a computer engineer, I'm CTO and co-founder at Octobot. I'm a big football soccer fan uh uh and I work on octobot uh in our doctobot We design, develop, and deploy uh custom software solutions. We use Django primarily for our back-end
Speaker 1: development. And we really enjoy transforming ideas into products people love. So both the company and myself are from Uruguay you are pretty uh you should pr feel free to do not know where Uruguay is because it's a small, very small country. R right down there. Uh it's about six thousand miles off something of here. Hooray for planes. Um And we are um and what I'm here to present today is uh a project that we undertook for the Urayan government, uh in which We created uh a single account for
Speaker 1: all services uh and that can be expanded into others. So I know some stuff about the US and I'm guessing you have users for or credentials for IERS, DMB, your health provider, banks, and so on. And all of those have different levels of assurance of who you are. You cannot create an account online if the bank does not know who you are. So what we did, we created a single sign -on for the URL government in which you have one account that you will use for either public services And also some other uh private services that need some form of assurance of uh who you are.
Speaker 1: If they don't need that, they can also use your service. So a bit of what we're going to talk about today, I'm gonna give you a brief context about Euroway mainly because uh It's uh not that much popular. Uh about the challenge that we face and what was and what were the peculiarities of it. Um the solution that we deployed, that part will be uh the first part will be um About security mostly. Then we'll take a peek, a slight peek under the hood, and I'll present something that we did that we found interesting to share with you guys, and some takeaways So let's get started. Your way. We are three and a half million people down there.
Speaker 1: When you are under five, you will you like to count that half million people. We have a centralized government. It's not a federal government, it's a centralized government. Around 70% of uh citizens there are internet users I would say it's a bit more, but nonetheless that's a third-party assessment. There are very good um access to broadband and 4G throughout the country. complex geography or something like that. So it's pretty available. And there's also a high availability of wave of web-capable devices. So Pretty much everybody or can access either a cell phone that has uh web capabilities or small laptops or something like that.
Speaker 1: Um okay. So digital URA. Uh all of that background actually place Uruguay on the road to for the last ten years uh pushing through in becoming uh one of the let's say leading digital nations regarding e-government. It's right now one of the nine countries in the D nine countries. It's a network of collaborative countries that push efforts to improve citizens' lives throughout technology. We have a national ID card. We have like forever had a national ID card and number. Each Uruyan has a primary key, let's say.
Speaker 1: Right now that card is uh electronic, so it has some things that we'll see right now. And there is e-government agency called AGESIC. Whenever I say this word, a sick, I'm actually saying those letters. So follow me please. Um Anagesik takes care of regulation and guidelines for uh laws and decrees and stuff like that. and also execution and orchestration of projects through third parties. They do not get involved directly into projects executing them. that. We would like to thank them for collaboration on on this talk. So a bit about the the ID card and what information is there.
Speaker 1: There's like a sample ID card where you have last names, first names, date of birth, and that's 9999. 999, it's our primary key. And this card uh reveals some stuff about uh what the registration procedure is. So um that car actually has uh For you to take that card, you have to give your fingerprints. Uh you got fingerprint scanned, you got a picture taken, and and they give you this card. That and you set a pin, you can actually set a pin in on the car and you can create digital signatures. So we have a registration, uh a high confidence on
Speaker 1: who that person is under registration. That's a standard procedure. That was a brief mention about that. So the government um as part of digital initiatives and so on, establish goals. So there are many of them, but the three that concern us for this talk today are Well, first they wanted to have a single point of contact, a single digital point of contact for all the services it provides. To be available for every citizen e-citizens to perform the procedures and operations digitally and remotely. So they can from the house do whatever is necessary with the government
Speaker 1: and also provide shared services and assets for third parties such as a single sign-on. So um what's the challenge here regarding the single sign-on? So the challenge is authentication. Why? Well because we must do a systems that can provide easy and secure um easy, secure and accessible authentication for all citizens. You cannot leave users outside your system. You have to support them all. Uh in in fact People that might have the hardest time using digital systems are probably the ones that can take most advantage of performing things remotely and from their houses.
Speaker 1: We also want to provide different integration protocols to reach out to as many organizations as possible. This is a win-win scenario, let's say if a lot of organizations uh are the citizens have a single sign-on to use on multiple organizations, public and private. If the If a lot of organizations use that system, the the citizens will have uh the organizations will have a trustworthy source of information regarding who that user is and how it performs authentication to reach out to their systems. So A lot of things went into the decision pipeline, but at one point
Speaker 1: uh they decided that they do not want it to go up with um an off-the-shelf solution, let's say. They wanted to build uh a single sign on provider. So what what should it provide? So what just should what should this solution provide? So first it should provide multi-factor accessible signal signal. Citizens should be able to provide who they are in an accessible way and secure way. Use a standard open protocol implementation. So don't go around inventing different stuff. Provide some basic profile information, name, last name. Maybe an email will be nice.
Speaker 1: And finally, one of the things that triggered this custom build is well you must do uh you must implement some way to To register on their system that yes, this guy is who he says he is, this user is who he says he is. And also use custom authentication factors. Our ID cards are capable of doing digital signature. I should be able to use my digital signature as a way of authenticating with a system. So all that had to be custom-made. Now how should it be? Those are like the requirements, but how should it be or the non-functional requirements? Well, it should be reliable.
Speaker 1: So it must be secure. Citizens must trust the system. The company the organization that integrates with the system must trust the system to be scalable. It should not have downtimes, it should not um suffer from unexpected and synchronized user uh usage, for instance if Uh tax deadline is coming up, you don't want that ID system, the doubt authentication system to go down uh it should be adaptable things change and this is uh um in a lot of ways uncharted territory so it's pretty important to be make it a solution adaptable should be open the government should be able to see what's going on in that system And it should be accessible, both in a
Speaker 1: maybe more classic disabilities way, but also regarding devices. So we want to out reach out to as many people as possible and that And that implies providing support for as many devices as possible. So with all of this in mind, the government said, okay. Call for proposals. Who can do this? So several providers went in and we said we can totally build this with Jenko. So um we worked with Django regularly and we said we can do this. We have never worked with the government before, but it's just like no This seems like something that we can do. So yeah, they
Speaker 1: say the same thing. Uh And so on. Not everybody was as on board as other teams. So uh the product owners were really thrilled to be working with Django and us, but that was not maybe the perception across the the the organization particularly given that this was a cornerstone project for them. So the solution. Um I'm by the way I'm here giving this talk so it went alright. Uh the solution. There it is.
Speaker 1: You can actually go online. If you have your passport and you know Spanish, you can actually create your account. Um If not, you can go and become a citizen and you'll be fully enabled to access the solution. It's really uh a web app. I'm not going to show it because people have recommended me not doing demo with conference Wi-Fi and so on. But you can go there. I hope we hope that you you see something that's worth it So some numbers. Right now there are about 350,000 citizens in the platform. That's about 10% of our country, so yay. Um but about a third of them are certified accounts.
Speaker 1: So you know when Twitter shows you the tick? So those are certified accounts that have either gone in presence to some certain stations where they can certify themselves or use their digital ID card to perform verification. And we have about those daily interactions. So what's in the box? It's not a complex product, and I want to see this right now because we're going to do a bit of security. And I want just to Say it's not a complex product. It's not a complex domain. The reality is not that much complex. Models are not that much complex. So there are two React apps, one, the one you'll see in that domain, the other are both for back
Speaker 1: office and certification purposes, and there is that Django project serving all of this. As w uh notable mentions, we have Celery doing some stuff and of course Django Rest framework. Um Should mention it's a must mention that library that uh basically provides you with an out-of-the-box OpenID Connect provider. by Juani Fioren. That's actually across is a neighbor from Argentina, I believe. So it's a great library. You should check it out if you ever faced in if you are ever faced with this situation. So security. One of the important things about security is understanding threats
Speaker 1: and avoiding incidents. In particular, understanding threats So I'm guessing most of you are developers and not construction side workers. If there are, you might not be surprised what follows, but For you developers, you go around and you'll see the signs on a construction site and say wear a helmet, wear war boots. And for us it's pretty evident that you should do that. It's like, yeah, of course. Why why wouldn't somebody wear a hat in a construction site? Things go off. Well big it's because you have to remind that because people that is there on an everyday environment is like normal for them. Like things fall, it doesn't happen to me, it's okay, no worries.
Speaker 1: But There should be signs like this in software development company. Now why aren't those there? Because The risks are not that evident. So you're faced with situations that are not that like, yeah, you know what? That huge crane might fall, and if I don't have my helmet on, I'm surely dead This is like, yeah, I couldn't deploy that, so I disable this flag over here. We are fine. You're not. Um so um Avoiding insecurities incidents is about understanding the risks and also doing some stuff that also construction sites do.
Speaker 1: Um that is um preparing uh or or working in a safer environment. Well first it's understanding. So we did threat modeling. First important thing threat modeling. Understand what you're facing regarding security. Second Do security by design. Make your project, your product, uh as secure as possible from the get-go. Do not uh do things that might introduce uh problems. In concrete, perform use list privilege and security in in depth. Those are security principles. And also finally, that's something that applies to construction side workers as well. Someone no one else is checking your work.
Speaker 1: You are the last line of defense in security. This is for all developers that we're working on this project. It's like You are the last line of defense. It's security, it's up to you eventually. There will be checks by others, there will be pen testing, reviews, security scannings and so on. But Assume that can fail. You are the last line of defense. So I'm gonna speak about uh threat modeling. Uh briefly what we did, uh threat modeling is an iterative process to identify uh problems, possible points of vulnerability. We find out that improves risk perception and vulnerability awareness.
Speaker 1: So developers are much more aware of what the problems really are, how the attacks work. and where vulnerability might pop up. Provides an in-depth understanding of the security settings that goes for Shango. uh and the protocols. So uh you can you can start to see why okay this token is sent over here and you can it's announced so don't use it twice because you you you start to get a sense of why things are there. And it has become a must-do security exercise for for software projects from our experience. There are several techniques. One is elevation of privilege.
Speaker 1: It's a card game. We think it's a fun approach to threat modeling. It's based on a stride classification of vulnerabilities. Go check it out, it's very good. You need a a bit of um you need a bit of a security background, but not that much. And it's open access made by Microsoft, you can download it and print it, and I think you can buy them as well. So what security practices came out of this? Well first establish non-default restrictive global uh use non-default restrictive global settings So don't go with the defaults if you don't know where what they are. Make endpoint declarations explicit in access. When you declare an API rend um
Speaker 1: endpoint Be sure that you know who has access to use that operation. This implies keeping permission granular and semantic, you know, when you write that permission being granular and semantic. Don't go about reinventing the wheel. So use standard crypto. Use standard protocols. Do not repeat yourself. You probably are introducing vulnerabilities if you are repeating code. Practice security in depth. Write a deployment configuration. Know what's going to run and what the communication paths are in your back-end deployments. Perform extra checks, even if it's in inner communication. Apply the least privilege principle. You should provide only the necessary data and operations to a user to perform the necessary
Speaker 1: transaction. And last but not least, don't forget about availability. One of the most common attacks is uh denial of service and don't make an attacker's life easier. Identify failure points and implement uh Protections such as throttling or good scalability guidelines. So these are the security practices that arise from threat modeling and security by design. We'll go about how they impacted specifically different aspects such as architecture. We regularly use, like always, 12 factors. Go check it out if you don't know them. I've placed these four because are the most important in our work for this project in this case. It allows us to evaluate
Speaker 1: good integrations, avoid uh setup mismatches and other problems that might introduce security vulnerabil vulnerabilities. Regarding the API, uh we didn't use microservices, it's not a complex reality. We use REST, REST framework. We did group the API by availability and scalability requirements. So the authentication endpoints is actually much more used than the management endpoint for authentication factors, like change your password. You don't do that Uh don't use default serializer. Be explicit about the serializing you're using and actually be slim about those serializers. Uh well and use throttling, we said that already. Regarding development, we use Git
Speaker 1: flow. Um it it it it's easier to handle if you have multiple environments like Test station, station two, pre-pro and prod. For our experience it's uh it's a better way to handle that without having uh code differences. We use a static code analysis at all levels, front-end, back-end, it's in force at CI. So we are we are looking at the code as it goes into the repo. We use Docker Dev Environment. There was a talk about this here, so uh go check it out. We use Go scripts, as in not Go the language, but Go scripts, check it out, they're pretty good. made by Mike Blunt. It avoided us uh CI dev environment mismatches.
Speaker 1: So we have this the CI and dev team run exactly the same scripts and commands. So that's pretty useful to avoid introducing vulnerabilities and we do peer reviews. Finally, log smart, log carefully, log plenty. Would you have to be careful about which data you're logging? you have to be um you have to log plenty of information because you want to be to have uh audit capabilities and perhaps detecting suspicious behavior Um but you have to look carefully because you don't want to log people's uh data in in an in an open accessible way. So infrastructure brief mention. This is run on OpenShift.
Speaker 1: It's a Kubernetes-based solution by Red Hat. It's run on a government cloud. There is an operator's team for the production environment, so we don't actually have access to that. Regarding deployment guidelines, what we did to actually address uh one problem that might have uh might arise regarding vulnerabilities have The deployment configuration being written by the dev team. So we actually write the the deployment template. And we can generate the different deployment files uh combining the template that's given by us, the parameters that's given by business people, and the secrets that's given um by the operator. So database passwords and so on. Uh it enables a formal communication between developer
Speaker 1: and operation developers and operators. So briefly, and because I have five minutes left, um, I wanted to cover some of the under the some a bit of what's going on under the hood regarding one point particularly that is the stateless multi-factor authentication. So multi-factor authentication I'm I'm I'm hoping. I'm guessing no I'm hoping that everybody has used multi-factor authentication once. But you actually have to provide not just a password, but a password, a token, uh one-time password, like such as Google Authenticators, something like that. Well in our case, our users, citizens, have authentication factor. And a login is the completion of all necessary
Speaker 1: uh factors for a given context. So if you have been on a travel, you know that if you log in with Google somewhere else Google is going to start asking for different stuff. That can happen, but what's important is that there is a variable factor list. It's not always the same list And it depends on the user. So uh a given user on one point might have just a password asked in i on a system. Um But in another context it might have a different uh set of challenges required. So um how do you keep track of a stateful transaction in a stateless scalable request
Speaker 1: environment? So one thing is using sessions. I'll keep tracking the session of what's going on with the user. Whenever the first request comes, I'll set you a session. Here you go. And I'll start keeping track of that interaction in the session. That goes to the DB The other alternative is using signed tokens. So sign tokens will enable us to actually Keep track of what's going on by sharing a token with the user on each request. We'll see that how that works right now. So It's a challenge-based authentication. The user, I hope the that size is readable from the from the back. The user will say, okay, I'm trying to log in Here is the
Speaker 1: my re my reply for the username challenge. The backend will say, okay, what are the list of your authentication factors? So you say okay, you need to send me the password. So he send me what's the next request for me to handle And also it will send me a token saying relevant stuff. In this case, what says is that uh I have passed no challenges yet. So I got my token. Next step, I'll send you my password. I have uh I'll send you what's the challenge I'm replying to, it's password, what's my password? That's not my password. And also, what's the token that you sent me before? So
Speaker 1: that token is signed, so they can actually the the back end can actually know, hey, I got this guy. Yeah, you need now TOTP So um but you have now passed the password challenge and that token is also signed. So the next one is okay here is my TOTP, my token, the last token you said that's already passed challenge, so the back end now says okay this has this gas hype has pass TOTP and password challenges. You're good to go. And that with that code I can follow up on a open ID connect. Authentication So the benefits of this, we avoid the database until uh necessary, so we'll provide a session once the user
Speaker 1: has fulfilled all necessary challenges. Um this also helps us avoid heavy queries because when we have to retrieve maybe profile data and so on, it's a bit heavier. And there's no affinity. It really doesn't matter which backend instance running uh handles my requests. To wrap up briefly in one minute. Um takeaways. Well first I don't know if you have had to sell Django recently, but if you go on the site, it will say things like Django is reassuringly fast, ridiculously fast, fully loaded, reassuringly secure. And well, it is. We know that, but for instance, people in the government did not know now did not know that and they have gotten to know it.
Speaker 1: Business people love the adaptability that these solutions have, and that is in great part because of Django, Python. Technology and operators love availability and scalability. From their words, we are the best behaved citizens of their cluster. Finally, Django security is reassuring. Django is real secure. We have been audited and stuff like that. But it's important to know why. Try elevation of privilege. Uh it will help you do some threat modeling and understand security settings. uh avoid disabling checks of course. Uh set non-default global configuration. So if you're going with the defaults. At least look at them or copy and paste them on your settings. Make your code and annotation explicit.
Speaker 1: Be semantic. Be clear. Somebody's going after you to look at the code, it has to know from the from from the description and and what's there, who has access to that, and work on availability. Thank you.
Speaker 2: What are you using salary for?
Speaker 1: Uh because we do tasks. For instance, we have to retrieve certificates that have been revoked for because if you get your national idea stolen, you go to a police department and say, I've been stolen. And they'll cancel that ID. So we have to regularly retrieve that list and perform some updates for instance.
Speaker 3: That was great. Thanks. Um what was a bottle what was a bottleneck that you ran into? as far as volume of users?
Speaker 1: Well there's we really anticipated more than maybe that's actually there actually scalability scalability has been working right so far. And even with things such as the our local IRS saying from one day to another, hey, you have one week to fulfill this and you have to do you have to use this authentication factor. So everybody was like On a couple of hours, traffic jumped 10-4 and no calls, no anything. So that's great. Uh that's in great part because of control factors. We really think that's uh it's uh it's a great path to to scalability. It's avoid a lot of pain points there.
Speaker 2: Yes. Thank you for the talk. It was excellent.
Speaker 1: Thank you.
Speaker 2: Did you write around this and and and and if if any, I'm sure you did. What top what type of tests?
Speaker 1: So there's um Um there was a testing bit on this that I stripped on the plane over here. But um we use the the default the everything is unit tested. Uh we use the default Django test um The Django test framework for React we use just.
Speaker 4: Great talk. How do you handle production support?
Speaker 1: Sorry?
Speaker 4: How do you handle production support since you guys are
Speaker 1: We are not operators. So there the it's actually handled there is we are the third line. So the first line is the government and they have this uh uh system support, then there's the specific uh our product owner support and there there's us. So we handle nine to five let's say. There are no no no special needs regarding
Speaker 5: Great talk.
Speaker 1: Thank you.
Speaker 5: So you mentioned that 10% of the population is using the service. And um s uh just above seventy percent of the population is connected to the internet. So that's about fourteen percent. Um I was wondering if you envision that number increasing over time.
Speaker 1: Yes.
Speaker 5: And if so How and like how can you drive that level of adoption?
Speaker 1: Okay, um disclosure. Um yes, that number I forgot to mention. It's increasing. It's been increasing steadily besides IRS. r sudden requests and so on, it's been increasing steadily from the fact that uh new organizations and new procedures and jumping into the the platform. So new use for instance if you want to travel to Brazil you need to get to get the yellow fever vaccination and to get yellow uh to get that vaccine you need to get a number where they require to so Every holiday season is like whoop and we're and it's increasing. It keeps increasing and it kee increases coverage. We don't actually have a saying or an interest
Speaker 1: besides the marvelous things that it can do regarding user increase. We we we are not driving c commercially the product, you know. But um yeah.
Speaker 4: This this seems like a very critical system. Were you guys involved in some penetration testing or some third-party evaluation of your software?
Speaker 1: Yeah. Actually, uh Uh hire we we did the work, but they had testing teams, they had penetration testing teams, they had security audits team in production. Systems are running that do that are doing other checks, for instance in traffic and so on. I'm not going to say a lot about that, but yeah, they did penetration testing from third parties.
Speaker 4: Yeah, thanks for the talk. Um do you see yourself working on other projects at the government or country level?
Speaker 1: Yes, actually we are right now working on the let's say next step. It's not actually the next step, but it's an associated project that's regarding authorization. So you will be able to provide authorization to organizations, both public and private, access to your personal data. For instance, you go to a health institution and a different one and they'll ask your previous health provider to access your health records. So you'll be able to provide on the authorization platform consent for that. It's very tightly related. This the authorization part. This is the authentication part, let's say. Uh
Speaker 5: as long as that uh in your country does this
Speaker 2: has any point uh for different level of uh the open data like uh Maybe there's a complete open data and there's uh uh some data is accessible by government and other like companies and some of those some of the data is only restri restrict to yourself.
Speaker 1: I could not understand your question correctly. Uh so there there is open data initiative back home. It does not work there is also uh privacy protection enforcement, so it does not actually combine the two And I don't know if that answers your question. I'm not s we can discuss it later in the hallway if you if you care. Thank you. One more.
Speaker 5: Okay. Thank you.
Speaker 1: Thank you all.
The project created one account that citizens can use across public services and, where appropriate, private services that need verified identity information. It was built as a Django application implementing standard OpenID Connect, with support for multiple authentication factors and national digital ID cards.
Discussed at 2:32The system needed accessible multi-factor authentication, standard open protocols, profile data, identity registration, and custom authentication using the country’s digitally signing ID cards. Those requirements led the team to build a provider specifically for Uruguay.
Discussed at 9:39The team used threat modeling and security-by-design, restrictive non-default settings, explicit and granular permissions, standard cryptography and protocols, least privilege, defense in depth, careful logging, throttling, and attention to availability. They also used static analysis, peer review, and security checks throughout development.
Discussed at 17:24The required factor list is variable: it depends on the user and the context. One login might require only a password, while another might require additional factors such as a one-time password or digital ID verification.
Discussed at 25:56Each authentication challenge returns a signed token recording which factors have already been completed. The client sends that token with the next challenge response, allowing any backend instance to continue the flow without database-backed session affinity; a session is created only after all required factors are complete.
Discussed at 26:42Celery runs background tasks such as regularly retrieving lists of revoked national ID certificates and updating the system when an ID has been reported stolen.
Discussed at 31:00The platform was designed for more demand than it initially received, and it handled a tenfold traffic jump when the tax authority suddenly required a particular authentication factor. The speaker attributed the result partly to twelve-factor practices and a design that avoided scalability bottlenecks.
Discussed at 31:31The development team is the third line of support: the government handles first-line support, followed by the product-owner support team, and the developers handle escalations during business hours.
Discussed at 32:58Yes. The project underwent third-party penetration testing and security audits, while production systems also performed additional monitoring and traffic checks.
Discussed at 35:00Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 14, 2026