There are two main ways to implement security in a system. They should always be used together, for reasons that will become obvious.
Security through obscurity
This means keeping critical parts of the system you’re designing a secret. Keeping your code closed source, not disclosing the structure of your system, etc.. The extreme example would be keeping the domain name of your website a secret…
With open-source systems, security by obscurity becomes almost impossible to implement: anyone can see the source code and grasp the security logic of the system. Nevertheless, open-source systems can and should implement some security through obscurity features.
Probably the most important thing to remember when considering this type of security is that it should never-ever (ever!) be implemented as the only, or main type of security (not even if your website’s address is kept secret).
Security by design
This means your system should be built from the ground up (even before the design phase, starting with the idea phase) with security in mind. In other words, security mechanisms should be built into the very structure of the system (as opposed to some security features being slapped on top of your system in post production, as if security is some sort of “self-contained” entity).
Security by design means disregarding all security assumptions (i.e. people are generally good, this or that is extremely unlikely to happen to me), except this one: an attacker knows the structure of your system, the security logic it uses, and has access to the source code (that is to say, security through obscurity was rendered useless).
Security through obscurity on top of security by design
After you’ve built your system secure by design, do employ security through obscurity as an extra level of protection. Assuming you’re building an open-source system, that will presumably be installed on production servers by others, you can still achieve some security through obscurity. Use that, however small the gain.
For example, see setting up the website’s system directory and vault directory. Or, when doing two-way encryption, hide the Initialization Vector (IV) string at a secret offset inside the encrypted string, instead of storing it separately. Same goes for hash salts.
In short, security by design is paramount and has priority, while obscuring things on top of it is feasible and desirable, and should not be neglected.