ARTICLE
No Default Passwords: How a RaptorGRC Deployment Refuses to Start Without One
Published 1 September 2026 · By P Larner
Secure by Design#containers#password policy#Secure by Design#default passwords#deployment
No Default Passwords: How a RaptorGRC Deployment Refuses to Start Without One
Illustration for: No Default Passwords: How a RaptorGRC Deployment Refuses to Start Without One
The second goal of CISA’s Secure by Design pledge asks a signer to “demonstrate measurable progress towards reducing default passwords”. CISA defines a default password as a universally shared password present by default across a product, and it sets a plain test for the end state. At the end of provisioning, only the customer should possess their credentials.
This is the one goal where RaptorGRC has nothing to reduce, because it never shipped a default password in the first place. That is a weaker claim than it sounds. “We have always been fine” is what every vendor says until someone greps the source. So this article shows the mechanism instead of asserting the outcome, and then it lists what is still missing around it.
The container will not start without a password
The application refuses
A RaptorGRC container seeds exactly one account on first run, the initial administrator. The password for that account is read from configuration, or from the RAPTORGRC_ADMIN_PASSWORD environment variable if configuration does not supply it. If neither is set, the application throws at startup and the container does not come up.
There is no fallback branch. There is no constant holding a value to use “if unset”, in that file or anywhere else in the product source. The failure mode of forgetting to set a password is an application that will not run, which is the correct failure mode, because a loud failure gets fixed and a quiet default does not.
Compose refuses one layer earlier
The shipped Docker Compose file enforces the same requirement before the application is even asked to start, using Compose’s required-variable syntax. If the variable is unset, the stack fails with an error that names the missing variable.
An operator therefore meets the requirement at the first command they run, which is where a requirement is cheapest to satisfy.
What is fixed, and why I am saying so
The initial administrator’s address is fixed at admin@raptorgrc.local. That is a known username. It is not a secret and I am not going to describe it as one.
A predictable account name on a predictable port matters if a deployment is exposed beyond the network it was designed for. Two things reduce that exposure. The credential itself is chosen by the installer and is unique to the instance, so knowing the username buys an attacker nothing but a target for guessing. And the deployment MFA policy, covered in the previous article in this series, can require a second factor for administrators.
What we do not do is force a password change or an MFA enrolment on that first sign-in. CISA’s example approaches include exactly that, a time-limited setup credential that disables itself once setup is complete. We have not built it, and that is a fair criticism of where we are rather than a nuance.
The password rules behind the credential
Letting the customer choose the password only helps if the product refuses a bad choice.
Length and complexity
RaptorGRC requires at least ten characters, with upper case, lower case, a digit and a non-alphanumeric character.
Length is doing most of the work there. Character-class rules are the weakest of the common controls and are well known to push people towards predictable substitutions, but ten characters with mixed classes is a reasonable floor and it is enforced in code rather than in a policy document.
There is no breach check
A password that satisfies every rule above and appears in every credential-stuffing list in circulation will be accepted. RaptorGRC does not check candidate passwords against a breach corpus.
This is the single change that would do most for real-world credential strength, and it is not implemented and not scheduled. It is also awkward for an offline product, because the obvious implementations call an online service. A downloadable hash set shipped with the image, or an optional integration a customer points at their own copy, are both feasible. Neither exists today.
Lockout is inherited rather than chosen
Account lockout runs on the framework defaults rather than a policy we set and documented. In practice that is five failed attempts followed by a short lockout, which is reasonable in itself.
The problem is that it is inherited. A control that exists because nobody overrode a default is a control that can vanish in a framework upgrade without anybody noticing. It should be explicit in code where a reviewer can read it, and it is not.
Demo data is where default credentials usually hide
Products rarely ship a default password on purpose. They ship one by accident, inside sample data that somebody forgot was enabled in production.
RaptorGRC does ship demo content. It is opted into during first-run setup by an already-authenticated administrator, it is off unless chosen, and the choice is written to the audit log so that it is visible afterwards that a human asked for it. The seeding routine returns immediately when the flag is false.
Development credentials for our own test environment exist, in a document in the product repository that is clearly marked as development only. They are fed to the development container through the same environment variable any other operator uses. They are not constants in shipped code, and no build embeds them.
The portal follows the same rule
The first staff account on raptorgrc.com is seeded from configuration in the same way, taking both address and password from settings the operator supplies, and the account is created with two-factor authentication already switched on.
Portal passwords currently require eight characters where the product requires ten. Of the two policies, ours is the weaker, which is the wrong way round for the system that is actually exposed to the internet.
The argument for a printed random password, taken seriously
There is a school of thought that says the strongest answer to this goal is not “the installer must supply a password” but “the product generates a unique random one and prints it once”, the way a router prints a per-device key on its base.
The argument is good. An installer-chosen password is only as strong as the installer, and a generated credential is unguessable by construction. It also removes an entire class of deployment failure where somebody sets a weak password because the container would not start without one and they were in a hurry.
The counter, in a container product, is that the generated value has to be surfaced somewhere, and every option for surfacing it is a leak. Container logs get shipped to a log aggregator. A file in a volume gets backed up. A value printed to a terminal in an automated deployment is lost, and the recovery path becomes a documented reset procedure that itself has to be secured.
Requiring the operator to supply a credential keeps the secret in whatever secret store they already run, which for the kind of organisation that deploys an air-gapped GRC product is usually a real one. That is why the design is what it is. It is a judgement, not an obvious truth, and the generated-credential approach would be defensible too.
What would move this beyond “we never had the problem”
Two changes would turn a structural absence into demonstrated progress.
The first is a time-limited setup credential that expires the moment first-run setup completes, so that the window in which a predictable administrator account exists with a human-chosen password is measured in minutes rather than in years.
The second is a breached-password check at the point a password is set, implemented in a way that works offline.
Neither is in flight today. Until one is, the honest position on goal two is that RaptorGRC starts from a good structural place and has not yet done additional work on top of it. That is why the pledge page marks this goal as shipped and says nothing more ambitious than that.
The full tracker is at /secure-by-design. What does and does not leave your network is set out at /transparency.
Run your GRC programme in your own network.
RaptorGRC Community Edition is free: every module, offline licence activation, nothing phones home.
Register / Download Contact us