juneau-sc-server
| Maven | |
|---|---|
| Jar | juneau-sc-server-10.0.0.jar |
| Links | Maven Central · Javadocs · Source |
Contents/Features
juneau-sc-server is the server component of the juneau-sc configuration
server. It is a standalone Juneau microservice built on juneau-microservice-jetty that:
- Clones or pulls a remote Git repository containing
.cfgfiles. - Exposes those files over a REST API at
GET /configs/{project}/{branch}. - Returns a JSON map containing up to two configuration layers: a shared
APPLICATIONdefault and aPROJECT-specific override.
The server depends on JGit for Git operations and on
juneau-rest-server / juneau-microservice-jetty for the REST layer.
Package overview
The juneau-sc-server module consists of the following classes:
Running the Server
The server is launched as a standard executable jar:
public class App {
public static void main(String[] args) throws Exception {
Microservice
.create()
.args(args)
.configurations(JettyConfiguration.class, AppConfig.class)
.build()
.start()
.startConsole()
.join();
}
@Configuration
public static class AppConfig {
@Bean
public Servlet loadConfigResource() {
return new LoadConfigResource();
}
}
}
The LoadConfigResource servlet is automatically mounted by Jetty at the path declared by its
@Rest(path="/configs/*") annotation.
Server Configuration File
The server reads its own settings from a juneau-server-config.cfg file located in the working
directory. The most important section is [GitServer]:
[Jetty]
# Port(s) to listen on — first available wins; 0 = random
port = 10000,0,0,0
[GitServer]
# Local filesystem path where the repo will be cloned
pathLocal = /var/lib/juneau-sc/config-repo
# Remote Git repository URI
gitRemote = https://github.com/my-org/my-config-repo.git
On each request the server:
- Checks whether
pathLocalexists.- If not, it runs a
git cloneofgitRemoteinto that directory. - If yes, it runs a
git pull.
- If not, it runs a
- Checks out the requested branch (
git checkout origin/{branch}). - Reads
application.cfg(shared defaults) and{project}.cfg(project override) from the local clone.
REST Endpoint
GET /configs/{project}/{branch}
| Segment | Description |
|---|---|
{project} | Name of the project; the server looks for {project}.cfg in the repo root. |
{branch} | Git branch to check out before reading files. |
Success response — 200 OK, Content-Type: application/json:
{
"APPLICATION": {
"value": "<raw text of application.cfg>"
},
"PROJECT": {
"value": "<raw text of {project}.cfg>"
}
}
If application.cfg is absent, the APPLICATION key is omitted.
If {project}.cfg is absent, the PROJECT key is omitted.
Example:
curl http://localhost:10000/configs/my-service/main
Security Considerations
The current implementation does not perform authentication or authorisation on the /configs endpoint.
Before exposing it outside a trusted network, consider:
- Adding HTTP Basic Auth or OAuth via a Juneau
RestGuard(wired through@Rest(guards=...)) or a servlet filter. - Restricting access at the network layer (firewall rules, service mesh policy).
- Storing Git credentials outside the config file (environment variables or a secrets manager) rather than hard-coding them.
GitControl itself does not hardcode credentials — its 5-argument constructor
(GitControl(localPath, remotePath, username, password, forcePush)) takes them as caller-supplied
parameters, and the 2-argument constructor defaults to anonymous transport with force-push disabled.
The residual risk is entirely at the call site: anything that wires up GitControl (e.g. an
AppConfig/App.java bean method) can still reintroduce the original problem by passing literal
credential strings:
// Unsafe — literal credentials checked into source control.
new GitControl(pathLocal, gitRemote, "svc-account", "hardcoded-token", false);
// Safe — credentials sourced from the environment (or a secrets manager) at startup, never committed.
new GitControl(pathLocal, gitRemote, System.getenv("GIT_USERNAME"), System.getenv("GIT_TOKEN"), false);
For the strongest option, GitControl also has a constructor that resolves the password/token from a
pluggable SecretStore: the secret
is looked up by key from the store resolved off a BeanStore (defaulting to an in-memory store), held as
a char[] rather than a String, and zeroed when the GitControl is closed. Contribute an
EnvVarSecretStore, an OS-keychain-backed store, or your own secrets-manager adapter to keep the token
out of both source and the checked-in juneau-server-config.cfg:
// Safest — the token never appears as a literal or a String; it comes from the contributed SecretStore.
BeanStore beanStore = new BasicBeanStore().addBean(SecretStore.class, new EnvVarSecretStore());
new GitControl(pathLocal, gitRemote, "svc-account", "GIT_TOKEN", beanStore, false);
Never hardcode the username/password arguments in application code or in the checked-in
juneau-server-config.cfg.
See Also
- juneau-sc Overview — architecture overview and repo layout
- juneau-config — the underlying config API
- juneau-microservice Basics — the microservice framework used by the server