feat: add --syncvalues flag and improve secret sharing #5
Reference in New Issue
Block a user
No description provided.
Delete Branch "eCommons/alakazam:secret-sync"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
WHOOYAA! this PR contains some features I was really missing! Thank you a lot. Especially the
get_secret_from_host()function I like! Hopefully it can be replaced someday by abra directly: toolshed/abra#694Maybe this function can be extended to read the secrets, even if there are no running containers: toolshed/organising#480 (comment) but this could be somewhat for another issue.
@ -552,2 +574,2 @@insert_secret(app1_domain, app1_secret, secret)logging.info(f"Shared secret {app2_secret} from {app2_domain} to {app1_domain} as {app1_secret}")# Target has secret but source doesn't, warn instead of copying back.# Copying target to source risks overwriting the correct source value.I'm not sure how you argue to remove the bidirectional secret sharing? The order which app is source or target should be quite irrelevant.
The condition
app2_secret_is_stored and not app1_secret_is_stored:ensures, that no secret will be overwritten. Because the secret of app1 doesn't exists.You're right, good catch. The whole logic is a bit hard to grasp because app1 and app2 refer to different apps depending on which call to share_secrets is being made from exchange_secrets. I think the edge case I wanted to solve here has already been solved by splitting the secret insertion and secret exchange into two phases in the secrets function, but I probably made that split after these changes.
For context: I have a case where it is important which app is the source: Rauthy doesn't support creating an OIDC client with a known secret. So Rauthy gets deployed first with a dummy value for the client secret. Then I use the initial-hooks to create a client with the Rauthy API and update the docker secret with the value that the API returns. Afterwards,
alakazam group secrets --syncvaluesshould only copy the secret value from rauthy to app2, not the other way around.I'm not sure if I exactly understand your rauthy flow but it sounds like the authentik saml workflow, for example with kimai.
First auhtentik needs to be deployed, to create the SAML certificate. Then the
secret-hookfor kimai runs this abra.sh function https://git.coopcloud.tech/coop-cloud/kimai/src/branch/main/abra.sh#L9 which calls the abra.sh function of authentik: https://git.coopcloud.tech/coop-cloud/authentik/src/branch/main/abra.sh#L362 to print the certificate and insert it as kimai secret.So in the end you use the Rauthy docker secrets only as "cache" to save the return value of the API and then share these values using
alakazam group secrets --syncvaluesto updated the dummy secret values that were generated randomly by abra in the first place?Did you tried to use the
secret-hooksfor that?Yes, exactly like this. Indeed seems similar to the saml workflow with kimai, that's another way to approach the problem. I did go over the authentik combine.yml, but missed that this one is different. I think ideally, I would like an SSO recipe to only have some commands to add a generic new client, and any app only have a generic connect-sso command. Alakazam should then contain the integration logic and configs, since alakazam handles that. Feels a bit cumbersome that for almost every integration app1 needs a compose.app2.yml file+secret and app2 needs a compose.app1.yml file+secret.
@ -558,0 +595,4 @@except RuntimeError as e:logging.warning(f"Could not read secret for comparison ({app1_domain}/{app2_domain}): {e}")continueif app2_value is None or app1_value != app2_value:Maybe it should be stated somewhere, that the secret of app2 will be overwritten, not only if it differs from the secret of app1, but also if the container is not running. The result will be the same, but for clarity.
@ -558,0 +603,4 @@update_secret(app2_domain, app2_secret, app1_value, app2_container)else:logging.warning(f"Secret mismatch: {app1_domain}/{app1_secret} differs from "Here you should adapt the warning if the container is not running, because if it is not, the warning
Secret mismatch: {app1_domain}/{app1_secret} differs from...would be incorrect. Instead a message likecouldn't compare secret values, because {app1} is not runningwould be good.@ -579,0 +652,4 @@if server:breakif not server:raise RuntimeError(f"Could not determine server for {domain}")Instead of this for loop, you could use
get_server_apps()@ -665,6 +775,23 @@ def insert_secret(domain: str, secret_name: str, secret: str) -> None:abra("app", "secret", "insert", domain, secret_name, "v1", secret)def update_secret(domain: str, secret_name: str, secret: str, containers: List) -> None:for a more intuitive function signature it would be good to pass a boolean
was_deployedinstead of the complete list of containers.@ -892,3 +1026,3 @@insert_secrets_from_conf(domain, app_config)run_secret_hooks(domain, app_config)exchange_secrets(app, instance_config, instance_apps)# Pass 2: exchange secrets between apps, then generate any remaining missing secrets.I really like the idea of splitting the secret insertion and secret exchange into two phases. I've never run into the case that I wanted to explicitly insert a secret first and the exchange it, therefore I never thought about this case.
38440692eeto888341c1dcThis looks perfect and can be merged :)