WIP
This page is a work in progress
Overview
Centralized configuration via mod-configuration is problematic from a security perspective. It provides a convenient mechanism for storing configuration, but the permission granularity is too coarse. Granting a user the ability to access an entry for one app means that they will also have access to ALL configuration entries.
One idea was proposed that all modules have a system interface which can be implement (or not), which presents a common interface for accessing configuration specific to various modules. This means the clients (the UI for instance) are presented a common interface for getting configuration instead of each module doing it their own way.
The "Configuration" System Interface
Modules can choose to implement this multiple interface "configuration"
- GET /configurations/entries
- GET /configurations/entries/<id>
- POST /configurations/entries
- PUT /configurations/entries/<id>
- DELETE /configurations/entries/<id>
Each of which would be protected by discrete permissions, e.g. mod-foo might have:
- foo.configurations.collection.get,
- foo.configurations.item.get (put/post/delete)
Storage Layer
UPDATE This part probably doesn't make much sense from a security standpoint - it put's us right back to where we started.
TBD... Just because the configuration APIs are distributed doesn't mean the configuration information must be. In the case of storage modules, they may choose to just store their configuration in postgres as doing so would probably require little effort. For business logic modules, or modules which have specific needs (e.g. the configuration is sensitive and should be encrypted, etc.) could choose to use a central configuration module for storage.
Here's where it might make sense to pull in additional technologies that are better suited to these requirements. See the 36583748section below. Having a module that presents a common interface in front of these technologies which is used internally (i.e. intended to be called only by other modules, not directly by clients) is an option that provides flexibility and opens the door to many potential benefits.
mod-configuration-storage
- Implements the configuration interface, or something that looks very similar.
- Uses a java interface to allow developers to add support for various underlying storage technologies - Maybe the default is just postgresql?
- Could enable multiple storage technologies, and the ability for the client to specify which storage they want to use...
- This should be implemented via something like attributes so that the client doesn't need to know which storage technologies are available... just that there's one that has the attributes it cares about.
- For instance - store this thing somewhere that's "secure". The module then looks for a configured storage that has the "secure" attribute, and stores it there.
- We'd have to allow for the administrator/operator to specify an order of precedence to help the module choose the right one in some cases.
- This should be implemented via something like attributes so that the client doesn't need to know which storage technologies are available... just that there's one that has the attributes it cares about.
Configuration
- Via json and/or properties config file(s)...
System property:
-DstorageConfigs=vault-config.properties,postgres-config.json
postgres-config.json:
{ "host":"localhost", "port":5432, "username":"folio", "password":"letmein", "database":"folio" }
vault-config.properties:
# Used by the factory class to match impl w/ config type=vault # the address of your vault # Default: http://127.0.0.1:8200 address={VAULT_ADDR} # whether or not to use SSL [true|false] # Default: false enableSSL=true # # NOTE: JKS-based config trumps PEM-based config. If you provide both JKS and PEM configs, # then the JKS config will be used. # You cannot "mix-and-match", providing a JKS-based truststore and PEM-based client auth data. # # the path to an X.509 certificate in unencrypted PEM format, using UTF-8 encoding ssl.pem.path={PEM_PATH} # # the path to a JKS truststore file containing Vault server certs that can be trusted #ssl.truststore.jks.path={TRUSTSTORE_PATH} # # the path to a JKS keystore file containing a client cert and private key #ssl.keystore.jks.path={KEYSTORE_PATH} # # the password used to access the JKS keystore (optional) #ssl.keystore.password={KEYWORD_PASSWORD}
Technologies
This list isn't intended to be comprehensive, just to give an idea of the types of things I'm referring to.
Other Considerations
- Migration of config data would need to be done on a per-module basis. We could effectively deprecate mod-configuration and then at some later date retire/end-of-life it entirely.