Skip to content

Commit d32eaa4

Browse files
committed
Merge remote-tracking branch 'origin/develop' into chore/extract-the-personal-vcs-access-token
Both sides add to LocalVCServletService rather than change the same code: the build agent hardening adds its four dependencies alongside the VCS access token service, and its shortcut returns before authenticateUser, so it never meets the AuthenticatedUser record. The bean budget is measured, not added up: 151 edges with a longest chain of 10, which is develop's 143 plus three account services and five build agent beans that turn out not to overlap. master.xml keeps the changelogs in timestamp order, and the new build agent test gets the constructor argument this branch added.
2 parents 0d84208 + 78903b4 commit d32eaa4

94 files changed

Lines changed: 6964 additions & 215 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci-bean-instantiations.yml

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,19 @@ jobs:
2626
MAX_STARTUP_DEPENDENCY_CHAIN_LENGTH: 10
2727
MAX_DEFERRED_CHAIN_LENGTH: 16
2828
MIN_INSTANTIATED_BEANS: 20
29-
# develop's 143 plus the three account-module services that hold the columns moved out of jhi_user - the VCS access
30-
# token, the recovery keys and the activity timestamps. Each is reached at startup through a consumer that is
31-
# already eager (LocalVCServletService, UserCreationService, UserService), and the class-level @Lazy they carry
32-
# cannot stop a consumer whose own constructor needs them. Measured with the check's own command: 146 edges,
33-
# longest chain 10.
34-
MAX_INSTANTIATED_BEANS: 146
29+
# develop's 143 plus two independent sets of eager beans, measured together at 151 edges, longest chain 10.
30+
#
31+
# Three account-module services hold the columns moved out of jhi_user - the VCS access token, the recovery keys
32+
# and the activity timestamps. Each is reached at startup through a consumer that is already eager
33+
# (LocalVCServletService, UserCreationService, UserService), and the class-level @Lazy they carry cannot stop a
34+
# consumer whose own constructor needs them.
35+
#
36+
# Five more come from the build agent access hardening, each pulling its own dependencies into the startup graph:
37+
# BuildAgentAddressRegistryService registers cluster connection listeners and a scheduled refresh,
38+
# BuildAgentNetworkPolicy parses the configured ranges and states at startup what this node enforces, and
39+
# ProxyProtocolAcceptor is installed on the ssh server before it accepts a connection. A lazy registry that
40+
# nothing instantiates at startup would stay empty, and no build agent could clone.
41+
MAX_INSTANTIATED_BEANS: 151
3542
MIN_DEFERRED_CHAIN_LENGTH: 1
3643

3744
steps:

docker/artemis/config/playwright-postgres.env

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,9 @@ ARTEMIS_CONTINUOUSINTEGRATION_BUILDTIMEOUT="30"
2424

2525
JENKINS_INTERNALURLS_CIURL="https://jenkins-test.artemis.in.tum.de"
2626
JENKINS_INTERNALURLS_VCNURL="https://artemis.in.tum.de"
27+
28+
# Jenkins with LocalVC is the one topology that still needs the shared build-agent credential: this stack runs localvc
29+
# without localci, so there are no build jobs and no clone tokens, and Jenkins is not an Artemis build agent. A value
30+
# other than the shipped `buildjob_password`, which the prod profile rejects as a published default.
31+
# checkov:skip=CKV_SECRET_6: fixture credential of the local E2E stack, not a deployment secret
32+
ARTEMIS_VERSIONCONTROL_BUILDAGENTGITPASSWORD="local-e2e-buildagent-not-a-deployment-credential"

docker/artemis/config/playwright.env

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,10 @@ ARTEMIS_TELEMETRY_ENABLED="false"
4343
# stacks run under the prod profile. Every service here reads this file, so all of them share one key.
4444
JHIPSTER_SECURITY_AUTHENTICATION_JWT_BASE64SECRET="${ARTEMIS_E2E_JWT_SECRET:?not set. Use one of the E2E runner scripts, or export it yourself: the output of openssl rand -base64 64, joined into a single line}"
4545

46-
# The prod profile also rejects the `buildjob_password` shipped in application-buildagent.yml / application-localvc.yml,
47-
# which the LocalCI stacks would otherwise inherit. Artemis and the build agent run in the same container here, so one
48-
# value covers both sides.
49-
# checkov:skip=CKV_SECRET_6: fixture credential of the local E2E/multi-node stacks, not a deployment secret
50-
ARTEMIS_VERSIONCONTROL_BUILDAGENTGITPASSWORD="local-e2e-buildagent-not-a-deployment-credential"
46+
# No shared build-agent credential here on purpose. This file is shared by every Playwright stack, and the LocalCI ones
47+
# run a node that refuses to start with one configured - build agents there authenticate with the clone token of the
48+
# build job they are running. The Jenkins with LocalVC stack is the exception and sets it in playwright-postgres.env,
49+
# which only that stack uses.
5150

5251
# Token is valid 3 days
5352
JHIPSTER_SECURITY_AUTHENTICATION_JWT_TOKENVALIDITYINSECONDS="259200"
@@ -68,3 +67,16 @@ MANAGEMENT_METRICS_EXPORT_PROMETHEUS_ENABLED="true"
6867

6968
# Activate E2E seed data via Liquibase
7069
SPRING_LIQUIBASE_CONTEXTS="prod,e2e"
70+
71+
# Nginx forwards the git ssh port at the TCP level and announces the real client with a PROXY protocol header
72+
# (proxy_protocol on, see docker/nginx/nginx.conf). Without this, the ssh server would attribute every connection to
73+
# nginx: git ssh rate limiting would share one bucket across all users and the access log would record the proxy.
74+
#
75+
# !!! NOT A PRODUCTION VALUE. Do not copy this line into a real deployment. !!!
76+
# These are the docker bridge ranges, which is where nginx sits in a compose stack. Compose assigns container addresses
77+
# dynamically, so there is no single address to name here. The cost is that anything able to connect from inside these
78+
# ranges could forge a client address and name an arbitrary ssh client; that is acceptable only because a compose test
79+
# stack is not a trust boundary and nothing else reaches port 7921 in it.
80+
# A real deployment must name its load balancer's own address, and should restrict port 7921 at the firewall so that
81+
# only the load balancer can reach it. See the "SSH behind a load balancer" section of the security documentation.
82+
ARTEMIS_VERSIONCONTROL_SSHPROXYPROTOCOL_TRUSTEDSOURCES="172.16.0.0/12,10.0.0.0/8,192.168.0.0/16"

docker/artemis/config/prod-multinode-fast.env

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,17 @@ JHIPSTER_SECURITY_AUTHENTICATION_JWT_TOKENVALIDITYINSECONDSFORREMEMBERME="259200
6363
ARTEMIS_VERSIONCONTROL_URL="http://localhost:8081"
6464
ARTEMIS_VERSIONCONTROL_USER="artemis_admin"
6565
ARTEMIS_VERSIONCONTROL_PASSWORD="local-e2e-admin-not-a-deployment-credential"
66-
ARTEMIS_VERSIONCONTROL_BUILDAGENTGITUSERNAME="buildjob_user"
67-
# checkov:skip=CKV_SECRET_6: fixture credential of the local E2E/multi-node stacks, not a deployment secret
68-
ARTEMIS_VERSIONCONTROL_BUILDAGENTGITPASSWORD="local-e2e-buildagent-not-a-deployment-credential"
66+
# Deliberately empty, and this is the point of it. Build agents authenticate with the clone token of the build job they
67+
# are running, and BuildJobGitService silently falls back to this shared pair whenever a job carries no token. With the
68+
# pair configured, a completely broken token path would still let every E2E test pass through the fallback, so nothing
69+
# here would ever fail. Leaving it empty makes the token path load-bearing: if it breaks, these tests break.
70+
#
71+
# This stack is the right place for it because it covers both agent topologies at once - node-3 is a standalone build
72+
# agent (a middleware client, whose origin is observable) and node-2 is co-located with a core node (no client
73+
# connection, so nothing to observe). Do not restore these values to "fix" a failing build; a failure here means the
74+
# token path is genuinely broken.
75+
ARTEMIS_VERSIONCONTROL_BUILDAGENTGITUSERNAME=""
76+
ARTEMIS_VERSIONCONTROL_BUILDAGENTGITPASSWORD=""
6977

7078
ARTEMIS_CONTINUOUSINTEGRATION_ARTEMISAUTHENTICATIONTOKENVALUE="demo"
7179
ARTEMIS_CONTINUOUSINTEGRATION_DOCKERCONNECTIONURI="unix:///var/run/docker.sock"
@@ -109,3 +117,8 @@ INFO_OPERATORNAME="TUM"
109117
SPRING_LIQUIBASE_CONTEXTS="prod,e2e"
110118

111119
MANAGEMENT_METRICS_EXPORT_PROMETHEUS_ENABLED="true"
120+
121+
# Same as the containerised multi-node setup: nginx forwards 7921 with proxy_protocol on. Here the Artemis nodes run
122+
# on the host, so the header arrives from the docker gateway, which is inside these ranges.
123+
# !!! NOT A PRODUCTION VALUE. Do not copy this line into a real deployment. !!! See prod-multinode.env for why.
124+
ARTEMIS_VERSIONCONTROL_SSHPROXYPROTOCOL_TRUSTEDSOURCES="172.16.0.0/12,10.0.0.0/8,192.168.0.0/16"

docker/artemis/config/prod-multinode.env

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,24 @@ JHIPSTER_SECURITY_AUTHENTICATION_JWT_BASE64SECRET="${ARTEMIS_E2E_JWT_SECRET:?not
4444
ARTEMIS_VERSIONCONTROL_URL='http://artemis-app-node-2:8080'
4545
ARTEMIS_VERSIONCONTROL_USER='artemis_admin'
4646
ARTEMIS_VERSIONCONTROL_PASSWORD='local-e2e-admin-not-a-deployment-credential'
47-
ARTEMIS_VERSIONCONTROL_BUILDAGENTGITUSERNAME='buildjob_user'
48-
# checkov:skip=CKV_SECRET_6: fixture credential of the local E2E/multi-node stacks, not a deployment secret
49-
ARTEMIS_VERSIONCONTROL_BUILDAGENTGITPASSWORD='local-e2e-buildagent-not-a-deployment-credential'
47+
# Deliberately empty: these nodes run local CI, which refuses to start with a shared build-agent credential configured.
48+
# Build agents authenticate with the clone token of the job they are running, which is what this stack exercises.
49+
ARTEMIS_VERSIONCONTROL_BUILDAGENTGITUSERNAME=''
50+
ARTEMIS_VERSIONCONTROL_BUILDAGENTGITPASSWORD=''
5051
ARTEMIS_CONTINUOUSINTEGRATION_ARTEMISAUTHENTICATIONTOKENVALUE='demo'
5152
ARTEMIS_CONTINUOUSINTEGRATION_DOCKERCONNECTIONURI='unix:///var/run/docker.sock'
5253
ARTEMIS_GIT_NAME='artemis'
5354
ARTEMIS_GIT_EMAIL='artemis@example.com'
55+
56+
# Nginx forwards the git ssh port at the TCP level and announces the real client with a PROXY protocol header
57+
# (proxy_protocol on, see docker/nginx/nginx.conf). Without this, the ssh server would attribute every connection to
58+
# nginx: git ssh rate limiting would share one bucket across all users and the access log would record the proxy.
59+
#
60+
# !!! NOT A PRODUCTION VALUE. Do not copy this line into a real deployment. !!!
61+
# These are the docker bridge ranges, which is where nginx sits in a compose stack. Compose assigns container addresses
62+
# dynamically, so there is no single address to name here. The cost is that anything able to connect from inside these
63+
# ranges could forge a client address and name an arbitrary ssh client; that is acceptable only because a compose test
64+
# stack is not a trust boundary and nothing else reaches port 7921 in it.
65+
# A real deployment must name its load balancer's own address, and should restrict port 7921 at the firewall so that
66+
# only the load balancer can reach it. See the "SSH behind a load balancer" section of the security documentation.
67+
ARTEMIS_VERSIONCONTROL_SSHPROXYPROTOCOL_TRUSTEDSOURCES="172.16.0.0/12,10.0.0.0/8,192.168.0.0/16"
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,15 @@
11
EUREKA_CLIENT_REGISTERWITHEUREKA=false
22
EUREKA_CLIENT_FETCHREGISTRY=false
3+
4+
# Nginx forwards the git ssh port at the TCP level and announces the real client with a PROXY protocol header
5+
# (proxy_protocol on, see docker/nginx/nginx.conf). Without this, the ssh server would attribute every connection to
6+
# nginx: git ssh rate limiting would share one bucket across all users and the access log would record the proxy.
7+
#
8+
# !!! NOT A PRODUCTION VALUE. Do not copy this line into a real deployment. !!!
9+
# These are the docker bridge ranges, which is where nginx sits in a compose stack. Compose assigns container addresses
10+
# dynamically, so there is no single address to name here. The cost is that anything able to connect from inside these
11+
# ranges could forge a client address and name an arbitrary ssh client; that is acceptable only because a compose test
12+
# stack is not a trust boundary and nothing else reaches port 7921 in it.
13+
# A real deployment must name its load balancer's own address, and should restrict port 7921 at the firewall so that
14+
# only the load balancer can reach it. See the "SSH behind a load balancer" section of the security documentation.
15+
ARTEMIS_VERSIONCONTROL_SSHPROXYPROTOCOL_TRUSTEDSOURCES="172.16.0.0/12,10.0.0.0/8,192.168.0.0/16"

docker/nginx/nginx.conf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,12 @@ stream {
4848
server {
4949
listen 7921;
5050
proxy_pass artemis;
51+
# specific Artemis change: announce the real client to the ssh server.
52+
# A plain TCP proxy_pass hides it, so every ssh connection would look like it came from this container:
53+
# git ssh rate limiting would share one bucket across all users, and the access log would record nginx.
54+
# Artemis reads the header when the connection comes from an address listed in
55+
# artemis.version-control.ssh-proxy-protocol.trusted-sources, which the shipped env files set to the
56+
# docker bridge ranges. Removing this line requires clearing that property, or ssh connections are refused.
57+
proxy_protocol on;
5158
}
5259
}

documentation/docs/admin/jenkins-localvc.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ artemis:
6464
user: root
6565
password: dummy # has to be set, but does not matter for LocalVC
6666
build-agent-git-username: jenkins
67-
build-agent-git-password: artemis_admin # choose some strong password and username (gives read access to all repositories)
67+
build-agent-git-password: <choose a strong password> # gives read access to all repositories, so do not reuse another credential. Values Artemis has published, artemis_admin among them, are rejected under the prod profile
6868
continuous-integration:
6969
user: artemis_admin
7070
password: artemis_admin
@@ -168,7 +168,7 @@ The following steps describe how to deploy a pre-configured version of the Jenki
168168
user: root
169169
password: dummy # have to be set, but does not matter for LocalVC
170170
build-agent-git-username: jenkins
171-
build-agent-git-password: artemis_admin # choose some strong password and username (gives read access to all repositories)
171+
build-agent-git-password: <choose a strong password> # gives read access to all repositories, so do not reuse another credential. Values Artemis has published, artemis_admin among them, are rejected under the prod profile
172172
continuous-integration:
173173
user: artemis_admin
174174
password: artemis_admin

documentation/docs/admin/production-setup/multiple-artemis-instances.mdx

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -589,28 +589,23 @@ You can make following adaptations to the `application-prod.yml`:
589589
590590
3. Furthermore, you will need some configuration related to version control and continuous integration.
591591
592-
Build agents require access to the VC server. How they authenticate for it is selected by
593-
`artemis.version-control.build-agent-use-ssh`, and the credentials below belong to only one of the two options:
594-
595-
- `true` (**recommended**): each agent generates an SSH key pair at startup and authenticates with it, so there is no
596-
shared credential to configure and `build-agent-git-username`/`build-agent-git-password` may be omitted entirely.
597-
- `false` (default, **deprecated**): the agents clone over HTTPS with the credentials below, which you must add to the
598-
build agents and to the localvc nodes alike.
599-
600-
The HTTPS credentials are therefore required only for that second configuration; the SSH setup is described after the
601-
example below.
592+
Build agents need to reach the VC server to clone repositories. They authenticate themselves: over HTTPS with the clone token of the build job they are running, or with an SSH key as described after the example below. Neither needs any configuration here.
602593
603594
```yaml
604595
artemis:
605596
version-control:
606597
url: <url-to-your-vc-server>
607598
default-branch: main # The branch that should be used as default branch for all newly created repositories. This does NOT have to be equal to the default branch of the VCS
608-
# Artemis admin credentials
609-
build-agent-git-username: buildjob_user # Replace with more secure credentials for production. Required for https access to localvc, and ignored when build-agent-use-ssh is true
610-
build-agent-git-password: buildjob_password # Replace with more secure credentials for production. Required for https access to localvc, and ignored when build-agent-use-ssh is true
611599
```
612600
613-
The order matters when you switch an existing installation over. Set `artemis.version-control.build-agent-use-ssh: true` on the build agents first — localvc nodes accept a registered agent's key regardless of their own setting, so builds keep working, and you can move agents one at a time — and only afterwards on the localvc nodes, where it stops that credential pair from granting build agents read access to every repository. Doing it in the other order breaks every agent still cloning over HTTPS. See [Build Agent Authentication](/admin/production-setup/security#build-agent-authentication).
601+
Build agents need no credential from you here. Choose in this order:
602+
603+
1. **SSH keys, recommended.** Set `artemis.version-control.build-agent-use-ssh: true` together with `ssh-template-clone-url` and `ssh-private-key-folder-path`. Every agent then generates its own key pair at startup and publishes only the public key — nothing to distribute or rotate. Roll it out on the build agents first (localvc nodes accept a registered agent's key regardless of their own setting, so builds keep working) and on the localvc nodes afterwards.
604+
2. **Build job clone tokens**, used automatically over HTTPS while `build-agent-use-ssh` is `false`. This needs no configuration at all.
605+
606+
Do **not** set `build-agent-git-username` or `build-agent-git-password` on these nodes — a node that runs local CI **refuses to start** with either of them configured, whether or not the agents use SSH. The pair is a static secret opening every repository that nothing here needs, and it belongs only to a localvc node without local CI, which is [Jenkins with LocalVC](/admin/jenkins-localvc).
607+
608+
Note that a multi-node setup terminates SSH on the load balancer, which hides the real client from the SSH server. Enable PROXY protocol in the nginx `stream` block and list the balancer in `artemis.version-control.ssh-proxy-protocol.trusted-sources` on every localvc node; the Docker Compose files in this repository already do both. See [Build Agent Authentication](/admin/production-setup/security#build-agent-authentication) for this and for restricting which networks build agents may connect from.
614609

615610
4. Configuration related to the execution of build jobs:
616611

0 commit comments

Comments
 (0)