-
Notifications
You must be signed in to change notification settings - Fork 33
chore(controlplane): Allow to setup NATS token based authentication #1944
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Signed-off-by: Javier Rodriguez <javier@chainloop.dev>
// TODO: add authentication options | ||
oneof authentication { | ||
// Token based authentication | ||
string token = 2 [(buf.validate.field).string.min_len = 1]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
out of curiosity, would this force us to use token or can the current deployments keep working?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the tests that I could run, since the authentication
field is optional, nothing will happen. The validation on the token
happens if the token field is in place. Some examples:
With this configuration no token is set:
server:
http:
addr: 0.0.0.0:8000
timeout: 10s
http_metrics:
addr: 0.0.0.0:0
grpc:
addr: 0.0.0.0:9000
# Way more configuration here
nats_server:
uri: nats://0.0.0.0:4222
We can run the server:
go run ./cmd/... --conf ./configs
DEBUG msg=config loaded: config.devel.yaml format: yaml
2025-04-03T10:48:17.690+0200 INFO {"component": "credentials/vault", "msg": "configuring vault", "address": "http://0.0.0.0:8200", "mount_path": "secret", "prefix": "chainloop-devel", "role": "writer"}
2025-04-03T10:48:17.698+0200 INFO {"component": "plugins", "msg": "loading plugins", "dir": "./plugins/bin", "pattern": "chainloop-plugin-*"}
2025-04-03T10:48:17.698+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=dependency-track, version=1.6, expectedMaterials=[SBOM_CYCLONEDX_JSON]"}
2025-04-03T10:48:17.698+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=smtp, version=1.0, expectedMaterials=[]"}
2025-04-03T10:48:17.698+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=discord-webhook, version=1.1, expectedMaterials=[]"}
2025-04-03T10:48:17.698+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=guac, version=1.0, expectedMaterials=[SBOM_CYCLONEDX_JSON SBOM_SPDX_JSON]"}
2025-04-03T10:48:17.698+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=slack-webhook, version=1.0, expectedMaterials=[]"}
2025-04-03T10:48:17.698+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=webhook, version=1.0, expectedMaterials=[SBOM_CYCLONEDX_JSON SBOM_SPDX_JSON]"}
2025-04-03T10:48:17.731+0200 INFO {"component": "natsAuditLogPublisher", "msg": "Stream Created or Updated", "name": "chainloop-audit", "subject": "audit.>"}
For all the following cases the NATS does not have any authentication configured.
Now let's add a token to the connection:
server:
http:
addr: 0.0.0.0:8000
timeout: 10s
http_metrics:
addr: 0.0.0.0:0
grpc:
addr: 0.0.0.0:9000
# Way more configuration here
nats_server:
uri: nats://0.0.0.0:4222
token: "notasecret"
go run ./cmd/... --conf ./configs
DEBUG msg=config loaded: config.devel.yaml format: yaml
2025-04-03T10:49:26.621+0200 INFO {"component": "credentials/vault", "msg": "configuring vault", "address": "http://0.0.0.0:8200", "mount_path": "secret", "prefix": "chainloop-devel", "role": "writer"}
2025-04-03T10:49:26.632+0200 INFO {"component": "plugins", "msg": "loading plugins", "dir": "./plugins/bin", "pattern": "chainloop-plugin-*"}
2025-04-03T10:49:26.632+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=dependency-track, version=1.6, expectedMaterials=[SBOM_CYCLONEDX_JSON]"}
2025-04-03T10:49:26.632+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=smtp, version=1.0, expectedMaterials=[]"}
2025-04-03T10:49:26.632+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=discord-webhook, version=1.1, expectedMaterials=[]"}
2025-04-03T10:49:26.632+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=guac, version=1.0, expectedMaterials=[SBOM_CYCLONEDX_JSON SBOM_SPDX_JSON]"}
2025-04-03T10:49:26.632+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=slack-webhook, version=1.0, expectedMaterials=[]"}
2025-04-03T10:49:26.632+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=webhook, version=1.0, expectedMaterials=[SBOM_CYCLONEDX_JSON SBOM_SPDX_JSON]"}
2025-04-03T10:49:26.648+0200 INFO {"component": "natsAuditLogPublisher", "msg": "Stream Created or Updated", "name": "chainloop-audit", "subject": "audit.>"}
The server starts correctly. If we now, leave the token
property set and empty:
server:
http:
addr: 0.0.0.0:8000
timeout: 10s
http_metrics:
addr: 0.0.0.0:0
grpc:
addr: 0.0.0.0:9000
# Way more configuration here
nats_server:
uri: nats://0.0.0.0:4222
token: ""
go run ./cmd/... --conf ./configs
DEBUG msg=config loaded: config.devel.yaml format: yaml
panic: validation error:
- nats_server.token: value length must be at least 1 characters [string.min_len]
Let's activate the NATS authentication and try without token:
server:
http:
addr: 0.0.0.0:8000
timeout: 10s
http_metrics:
addr: 0.0.0.0:0
grpc:
addr: 0.0.0.0:9000
# Way more configuration here
nats_server:
uri: nats://0.0.0.0:4222
go run ./cmd/... --conf ./configs
DEBUG msg=config loaded: config.devel.yaml format: yaml
2025-04-03T10:56:11.060+0200 INFO {"component": "credentials/vault", "msg": "configuring vault", "address": "http://0.0.0.0:8200", "mount_path": "secret", "prefix": "chainloop-devel", "role": "writer"}
2025-04-03T10:56:11.068+0200 INFO {"component": "plugins", "msg": "loading plugins", "dir": "./plugins/bin", "pattern": "chainloop-plugin-*"}
2025-04-03T10:56:11.068+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=dependency-track, version=1.6, expectedMaterials=[SBOM_CYCLONEDX_JSON]"}
2025-04-03T10:56:11.068+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=smtp, version=1.0, expectedMaterials=[]"}
2025-04-03T10:56:11.068+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=discord-webhook, version=1.1, expectedMaterials=[]"}
2025-04-03T10:56:11.068+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=guac, version=1.0, expectedMaterials=[SBOM_CYCLONEDX_JSON SBOM_SPDX_JSON]"}
2025-04-03T10:56:11.068+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=slack-webhook, version=1.0, expectedMaterials=[]"}
2025-04-03T10:56:11.068+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=webhook, version=1.0, expectedMaterials=[SBOM_CYCLONEDX_JSON SBOM_SPDX_JSON]"}
2025-04-03T10:56:11.087+0200 INFO {"msg": "closing the data resources"}
panic: failed to connect to nats: nats: Authorization Violation
With token:
server:
http:
addr: 0.0.0.0:8000
timeout: 10s
http_metrics:
addr: 0.0.0.0:0
grpc:
addr: 0.0.0.0:9000
# Way more configuration here
nats_server:
uri: nats://0.0.0.0:4222
token: "notasecret"
go run ./cmd/... --conf ./configs
DEBUG msg=config loaded: config.devel.yaml format: yaml
2025-04-03T10:57:51.161+0200 INFO {"component": "credentials/vault", "msg": "configuring vault", "address": "http://0.0.0.0:8200", "mount_path": "secret", "prefix": "chainloop-devel", "role": "writer"}
2025-04-03T10:57:51.170+0200 INFO {"component": "plugins", "msg": "loading plugins", "dir": "./plugins/bin", "pattern": "chainloop-plugin-*"}
2025-04-03T10:57:51.171+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=dependency-track, version=1.6, expectedMaterials=[SBOM_CYCLONEDX_JSON]"}
2025-04-03T10:57:51.171+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=smtp, version=1.0, expectedMaterials=[]"}
2025-04-03T10:57:51.171+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=discord-webhook, version=1.1, expectedMaterials=[]"}
2025-04-03T10:57:51.171+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=guac, version=1.0, expectedMaterials=[SBOM_CYCLONEDX_JSON SBOM_SPDX_JSON]"}
2025-04-03T10:57:51.171+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=slack-webhook, version=1.0, expectedMaterials=[]"}
2025-04-03T10:57:51.171+0200 INFO {"component": "plugins", "msg": "loaded", "type": "built-in", "plugin": "id=webhook, version=1.0, expectedMaterials=[SBOM_CYCLONEDX_JSON SBOM_SPDX_JSON]"}
2025-04-03T10:57:51.195+0200 INFO {"component": "natsAuditLogPublisher", "msg": "Stream Created or Updated", "name": "chainloop-audit", "subject": "audit.>"}
Basically the key here is not rendering the token
field on the nats_server
configuration object if there is no authentication.
This is the default configuration being rendered if the token value is not passed:
stringData:
config.secret.yaml: |
data:
database:
driver: pgx
source: postgresql://chainloop:chainlooppwd@chainloop-postgresql:5432/chainloop-cp
nats_server:
uri: "nats://aaa:4222"
credentials_service:
secretPrefix: "chainloop"
vault:
address: "http://chainloop-vault-server:8200"
token: "notasecret"
If we pass a token with --set controlplane.nats.token="notasecret"
stringData:
config.secret.yaml: |
data:
database:
driver: pgx
source: postgresql://chainloop:chainlooppwd@chainloop-postgresql:5432/chainloop-cp
nats_server:
uri: "nats://aaa:4222"
token: "notasecret"
credentials_service:
secretPrefix: "chainloop"
vault:
address: "http://chainloop-vault-server:8200"
token: "notasecret"
If we pass an empty token, --set controlplane.nats.token=""
, it will simply not render:
stringData:
config.secret.yaml: |
data:
database:
driver: pgx
source: postgresql://chainloop:chainlooppwd@chainloop-postgresql:5432/chainloop-cp
nats_server:
uri: "nats://aaa:4222"
credentials_service:
secretPrefix: "chainloop"
vault:
address: "http://chainloop-vault-server:8200"
token: "notasecret"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so about the rollout, if we add the token to the clients but not to the server, would it work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's the second example, the NATS server will ignore the authentication token if it does not have any configured.
This patch updates the control plane server configuration to optionally accept a NATS authentication token for client connections to the NATS server. Additionally, the chart templates have been modified to support passing the token via the new
controlplane.nats.token
configuration option.