"Security maintainability is the elephant in the living room; people know there's an awful problem but are generally too polite to mention it (especially as we don't really know what to do with the beast)." [1]
Ross Anderson
Security solutions are built to solve very specific cases, with very specific assumptions, parameters, and environments. Because the real world changes, security solutions gradually get out of sync with their deployment environment [2]. Sometimes the effects are undesirable, such as with key/secret leaks. There are also weird and cryptic side-effects; for example, a distributed system needs a PKI to scale, but PKIs are brittle and centralized, and do not scale [3] or, heavens forbid, you need to modify your naming scheme [4]. How do we keep up with real-world changes as efficiently as possible?
Dig around in any nontrivial security-related application, and you'll find places where it is hard to tell where the application stops and the security solution begins. The "spaghettiness" seems to worsen with the software's age, complexity, number of upgrades/patches, number of developers, and so on. There seems to be an inherent conflict of interests. On one hand, you want to maximize the flexibility of the application, add features, and whatnot; on the other, you want to have the best security available.
In a dynamic environment, this sounds brittle. Of course, there's little wonder why: A complete redesign to ensure harmony between application and security is costly. However, it's sometimes easier to redesign than to fix, which is why we get incompatible upgrades: SSH1 versus SSH2, SSL2 versus TSL, Win95 versus Win2000, and so on. For example, replacing a nontrivial security solution based on shared-key technology with one based on public-key technology is a major undertaking. If you don't think so, try modifying, say, Firefox to use password-based PGP instead of SSL/TSLit's possible, but insanely difficult. Obol (http://www.pasta.cs.uit.no/~perm/Obol/) is a freely available security protocol programming language that has been built to address this problem.