Skip to content

transfer oauth creds as part of certificate bundle - #698

Merged
stejskalleos merged 5 commits into
theforeman:masterfrom
arvind4501:oauth
Jul 29, 2026
Merged

transfer oauth creds as part of certificate bundle#698
stejskalleos merged 5 commits into
theforeman:masterfrom
arvind4501:oauth

Conversation

@arvind4501

@arvind4501 arvind4501 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Why are you introducing these changes? (Problem description, related links)

Proxy deployment currently requires passing --oauth-consumer-key and --oauth-consumer-secret manually with deploy-proxy command. Those credentials already exist on the Foreman server and are required for the proxy to communicate with Foreman.
With these changes oauth credentials will travel with the bundle instead of being supplied as extra CLI parameters.

What are the changes introduced in this pull request?

  • Include Foreman OAuth consumer key/secret in the tarball produced by certificate-bundle
  • During deploy-proxy, read OAuth credentials from the extracted bundle (/var/lib/foremanctl/certs/) when flavor == foreman-proxy-content
  • Remove --oauth-consumer-key / --oauth-consumer-secret from deploy-proxy

How to test this pull request

Steps to reproduce:

  • Deploy Foreman, then generate a proxy bundle:
    ./foremanctl auth-bundle proxy.example.com

  • Confirm the tarball includes OAuth files:
    tar -tzvf /var/lib/foremanctl/certs/bundles/proxy.example.com.tar.gz | grep oauth

  • Deploy the proxy without OAuth CLI flags:
    ./foremanctl deploy-proxy --flavor foreman-proxy-content --auth-bundle <bundle> --foreman-fqdn <foreman-fqdn>

  • Confirm extracted files exist on the proxy:
    /var/lib/foremanctl/certs/foreman-oauth-consumer-key

Checklist

  • Tests added/updated (if applicable)
  • Documentation updated (if applicable)

Comment thread src/roles/foreman_proxy/tasks/oauth_from_bundle.yml Outdated
Comment thread tests/flavor/foreman-proxy-content/oauth_test.py
Comment thread src/roles/foreman_proxy/tasks/oauth_from_bundle.yml Outdated
Comment thread src/roles/certificate_bundle/tasks/main.yml Outdated
@arvind4501
arvind4501 force-pushed the oauth branch 2 times, most recently from 287645f to ae9ce9c Compare July 23, 2026 12:43
@ehelms

ehelms commented Jul 23, 2026

Copy link
Copy Markdown
Member

I think it would be nice to combine the extraction into a single extraction step of the bundle for everything in it, getting placed in the right locations.

@@ -0,0 +1,27 @@
---
- name: Load OAuth credential from certificate bundle - {{ oauth_from_bundle_credential }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way I wanted to design the bundle was for it to be "throw away" after initial use. Can the oauth be loaded into files in the state directory and stored for reading like it is in the deploy Foreman case?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way it's implemented right now, the bundle.tar.gz is throw away. The reading here happens from a file on disk after extraction from a sub-folder of our state directory on the target node.

Emphasis on "target node", as that breaks the "can it be the same as Foreman" case.
In the Foreman case we store the data on the control node (lookups run on the control node), not the target node.

We could "double extract" the bundle: once the certs part on the target, and the oauth part on the controller, but I'm not sure that complexity is worth it?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like what you are really saying is that the certificates should exist on the control node, and normalize that everything in /var/lib/foremanctl should be state?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maaaaaaaaaaybe. (it's friday afternoon)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that something we need to tackle now?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO no

Comment thread tests/flavor/foreman-proxy-content/oauth_test.py Outdated
Comment thread src/roles/certificates/tasks/extract.yml
Comment thread src/roles/certificates/tasks/extract.yml Outdated
@ehelms

ehelms commented Jul 24, 2026

Copy link
Copy Markdown
Member

We could switch from certificate_bundle to auth_bundle but that's an idle thought :)

certificate_bundle_output_directory: "{{ certificates_ca_directory }}/bundles"
certificate_bundle_server_ca_certificate: "{{ certificate_bundle_ca_certificate }}"
certificate_bundle_oauth_consumer_key_file: # noqa: no-empty-defaults
certificate_bundle_oauth_consumer_secret_file: # noqa: no-empty-defaults

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just omit these if they are empty? What's the value of having empty defaults?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed them. The empty defaults only had value when paired with the when: ... is exists guards on the copy tasks, the empty value helped to safely skip tasks when caller did not provide these vars, but in our case certificate-bundle playbook always sends these vars so good to remove

src: "{{ certificate_bundle_oauth_consumer_key_file }}"
dest: "{{ certificate_bundle_build_directory.path }}/certs/oauth/foreman-oauth-consumer-key"
mode: '0440'
when: certificate_bundle_oauth_consumer_key_file is exists

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this file doesn't exist should we skip over that? Or let it error? Seems fairly serious if it doesn't exist.

@arvind4501

Copy link
Copy Markdown
Contributor Author

We could switch from certificate_bundle to auth_bundle but that's an idle thought :)

maybe, with that do we want to change the command from foremanctl certificate-bundle <hostname> to foremanctl auth-bundle <hostname>, or just the role name? i think it boils down to what command name we want to expose to users :)

@evgeni

evgeni commented Jul 27, 2026

Copy link
Copy Markdown
Member

We could switch from certificate_bundle to auth_bundle but that's an idle thought :)

maybe, with that do we want to change the command from foremanctl certificate-bundle <hostname> to foremanctl auth-bundle <hostname>, or just the role name? i think it boils down to what command name we want to expose to users :)

Given the bundle now has more than certificates, I think changing the command name makes sense.

@stejskalleos stejskalleos self-assigned this Jul 27, 2026
- name: Generate auth bundle on quadlet
run: |
./foremanctl certificate-bundle proxy.example.com \
./foremanctl auth-bundle proxy.example.com \

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SatelliteQE/robottelo#22277
for doc PR, i hope to get this PR in before that 😄

Comment thread src/playbooks/certificate-bundle/certificate-bundle.yaml

@Gauravtalreja1 Gauravtalreja1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK, Tested with foremanctl-3.0.0.develop-3.20260724120313055342.pr698.143.g745e9f5.el9.noarch 🍏

Steps: deployed Foreman server → generated auth bundle → verified OAuth files in tarball → deployed proxy without --oauth-consumer-key/secret → verified OAuth files extracted on proxy with correct permissions → confirmed proxy registered with Foreman and features refresh works → verified old CLI flags are rejected.

One minor issue found: the fail-early check for missing OAuth files doesn't trigger when using a bundle generated before this PR (old certificate-bundle), since the extraction step excludes files outside certs/ and private/, which isn't properly handled in Ansible stdout as shown below:

TASK [certificates : Extract OAuth credentials from bundle] ***********************************************************************************************************************************
fatal: [localhost]: FAILED! =>
    changed: false
    msg: |-
        Failed to find handler for "/root/.ansible/tmp/ansible-tmp-1785238624.9872594-1828915-110760222717154/source". Make sure the required command to extract the file is installed.
        Command "/usr/bin/gtar" could not handle archive: Unable to list files in the archive: tar (child): bzip2: Cannot exec: No such file or directory
        tar (child): Error is not recoverable: exiting now
        /usr/bin/gtar: Child returned status 2
        /usr/bin/gtar: Error is not recoverable: exiting now

        Command "/usr/bin/unzip" could not handle archive:   End-of-central-directory signature not found.  Either this file is not
          a zipfile, or it constitutes one disk of a multi-part archive.  In the
          latter case the central directory and zipfile comment will be found on
          the last disk(s) of this archive.
        note:  /root/.ansible/tmp/ansible-tmp-1785238624.9872594-1828915-110760222717154/source may be a plain executable, not an archive
        unzip:  cannot find zipfile directory in one of /root/.ansible/tmp/ansible-tmp-1785238624.9872594-1828915-110760222717154/source or
                /root/.ansible/tmp/ansible-tmp-1785238624.9872594-1828915-110760222717154/source.zip, and cannot find /root/.ansible/tmp/ansible-tmp-1785238624.9872594-1828915-110760222717154/source.ZIP, period.

        Command "/usr/bin/gtar" could not handle archive: Unable to list files in the archive: tar (child): zstd: Cannot exec: No such file or directory
        tar (child): Error is not recoverable: exiting now
        /usr/bin/gtar: Child returned status 2
        /usr/bin/gtar: Error is not recoverable: exiting now

        Command "/usr/bin/gtar" found no files in archive. Empty archive files are not supported.
        Command "/usr/bin/gtar" could not handle archive: Unable to list files in the archive: xz: (stdin): File format not recognized
        /usr/bin/gtar: Child returned status 1
        /usr/bin/gtar: Error is not recoverable: exiting now

But this is a minor edge case which I discussed with @arvind4501 ; users won't have old auth-bundles in practice so we can safely ignore this.

LGTM 🍏

Comment thread docs/user/certificates.md
Both flags are **not persisted** in foremanctl’s answers file (one-shot).

### Certificate Bundle for Secondary Systems
### Auth Bundle for Secondary Systems

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the parameters.md, we still show --foreman-proxy-oauth-consumer-key & --foreman-proxy-oauth-consumer-secret in the Undetermined section. Should we update that as well?

@arvind4501 arvind4501 Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, in which section should we add droped parameters which existed on foreman-installer but not in foremanctl? or just remove them from undetermined

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In #532 I used "unmapped" to explicitly call them out. how about that?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perfect, thanks

Comment thread src/roles/oauth_from_bundle/defaults/main.yml
Comment thread src/vars/base.yaml
@arvind4501

Copy link
Copy Markdown
Contributor Author

One minor issue found: the fail-early check for missing OAuth files doesn't trigger when using a bundle generated before this PR (old certificate-bundle), since the extraction step excludes files outside certs/ and private/, which isn't properly handled in Ansible stdout as shown below:

IMHO, since bundle generation changes are not released in any version, we won't need to handle upgrades. also i expect generated bundle to have oauth/ in it and we are validating that after extraction

Comment thread docs/user/parameters.md Outdated
Comment on lines +139 to +140
| `--foreman-proxy-oauth-consumer-key` | OAuth consumer key for Smart Proxy | Not supported |
| `--foreman-proxy-oauth-consumer-secret` | OAuth consumer secret for Smart Proxy | Not supported |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically "Not required, automated", right?

@ekohl

ekohl commented Jul 28, 2026

Copy link
Copy Markdown
Member

maybe, with that do we want to change the command from foremanctl certificate-bundle <hostname> to foremanctl auth-bundle <hostname>, or just the role name? i think it boils down to what command name we want to expose to users :)

Bike shedding a bit: proxy-identity-bundle perhaps? This makes it clear it's for a proxy, not for the Foreman server itself.

@arvind4501

Copy link
Copy Markdown
Contributor Author

maybe, with that do we want to change the command from foremanctl certificate-bundle <hostname> to foremanctl auth-bundle <hostname>, or just the role name? i think it boils down to what command name we want to expose to users :)

Bike shedding a bit: proxy-identity-bundle perhaps? This makes it clear it's for a proxy, not for the Foreman server itself.

when i see proxy-identity-bundle i wonder is there any certificate bundle we need for foreman server(i guess no?). as if no other entity(except proxy) needs auth-bundle we might not need to add proxy-*, also we generate bundle from server, i am happy to update. opinions?

@evgeni

evgeni commented Jul 29, 2026

Copy link
Copy Markdown
Member

I like the current auth-bundle.
(Also, technically, there is nothing proxy-specific in the bundle, you could use it to setup another Foreman [without Canldepin] too)

@ekohl

ekohl commented Jul 29, 2026

Copy link
Copy Markdown
Member

That's fair. Given long term I'd love to get rid of the bundle anyway I can live the auth-bundle name.

@stejskalleos
stejskalleos merged commit 99da444 into theforeman:master Jul 29, 2026
27 of 29 checks passed
@arvind4501
arvind4501 deleted the oauth branch July 30, 2026 06:46
@arvind4501 arvind4501 mentioned this pull request Jul 30, 2026
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants