diff --git a/.gitignore b/.gitignore index 85e7c1d..ae91c4c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /.idea/ +/.vagrant/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2dde510 --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +SUBDIRS = cacert_resources oidc_app oidc_idp oidc_registration + +all: cacert_resources oidc_app/demo-app oidc_idp/cacert-idp oidc_registration/cacert-oidc-registration + +cacert_resources: force_look + echo building JS and CSS resources + cd cacert_resources ; $(MAKE) $(MFLAGS) + +oidc_app/demo-app: force_look + echo building demo app : $(MAKE) $(MFLAGS) + cd oidc_app ; $(MAKE) $(MFLAGS) + +oidc_idp/cacert-idp: force_look + echo building CAcert IDP : $(MAKE) $(MFLAGS) + cd oidc_idp ; $(MAKE) $(MFLAGS) + +oidc_registration/cacert-oidc-registration: force_look + echo building CAcert client registration: $(MAKE) $(MFLAGS) + cd oidc_registration ; $(MAKE) $(MFLAGS) + +clean: + echo cleaning up in . + -for d in $(SUBDIRS) ; do ( cd $$d; $(MAKE) clean ); done + +force_look: + true + +.PHONY: all clean diff --git a/README-extra.md b/README-extra.md new file mode 100644 index 0000000..9af1b0a --- /dev/null +++ b/README-extra.md @@ -0,0 +1,14 @@ +### Extra PostgreSQL Notes + +PostgreSQL should have been installed automatically as part of the installation of Debian 12. + +see /usr/share/doc/postgresql-common for some documentation + +If, for some reason, that installation is incomplete, it is best to re-install PostgreSQL in your Debian 12. + +```shell +sudo apt update +sudo apt install postgresql postgresql-contrib +``` + + diff --git a/README.md b/README.md index cce68f0..8977e70 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,176 @@ git config submodule.recurse true ## Get started -- [setup Hydra](https://code.cacert.org/cacert/oidc-hydra-config/src/branch/main/README.md) -- build CAcert web application resources +Make sure you have the necessary prerequisites installed (tested on Debian 12 +Bookworm) and `~/.local/bin` in your `$PATH` variable: + +Those prerequisites include: +git -- of course +PostgreSQL -- see README-extra.md +Hydra -- see hydra_config/README.md + +Further items are installed here: + +```shell +sudo apt update +sudo apt install make mkcert python3-pip python3-venv golang-go yarnpkg +mkdir -p $HOME/.local/share/virtualenvs ~/.local/bin +python3 -m venv $HOME/.local/share/virtualenvs/ansible +$HOME/.local/share/virtualenvs/ansible/bin/pip install ansible +ln -s $HOME/.local/share/virtualenvs/ansible/bin/ansible* $HOME/.local/bin/ +export PATH=$HOME/.local/bin:$PATH +``` + +*Note:* It is a good idea to put the `PATH` export line into your `.bashrc` or +`.zshenv`. + +### Initial Configuration +Each of the sub-directories contains instructions for creating or editing +a configuration file and, usually, certificates. + +The first that must be performed are the instructions found in the "hydra_config" +sub-directory. + + In that one, you must first install Hydra before you continue. + + Next, create a certificate and key pair using mkcert, set your database + password, and generate a secret key for Hydra. + + Following that, you need to create the Hydra configuration file, hydra.yaml. + + Finally, after starting Hydra, you need to create a Hydra Client, using the + command found at the bottom of the README.md in that directory. Save the + values returned from that command. + +Next, go in to the cacert_resources sub-directory and follow the directions +in that README.md regarding installing nodejs and webpack. + +Third, go in to the oidc_app sub-directory. + + There, you again need to create a certicate and key pair using mkcert. + + Create the configuration file, resource_app.toml, using the values created + from the Hydra command described in the hydra_config README.md, and the two + secret keys as described in the current README.md file. + +Next, the oidc_idp sub-directory. + + Again, you will need to create the certificate and key pair using mkcert. + + Create the configuration file, idp.toml, using only the a secret key, as + described in the current README.md file. + +Finally, change into the oidc_registration sub-directory. + + There, you will find detailed instructions for certificate creation for + this module. + + As well, after creating a secret key, you will create the configuration + file, registration.toml. + +### Continuing + +At this point, you should have created all of the certificates and configuration files +needed by this system. + +### Build the applications + +Use `make` to build the web app resources and applications: + + +### Install the language translation tool + +```shell +go install github.com/nicksnyder/go-i18n/v2/goi18n@latest +``` + + +### Build the applications + +Use `make` to build the web app resources and applications: + +```shell +make +``` + +## Deployment options + +There are two deployment options for the Hydra server and for the custom applications: + +1. local deployment +2. Vagrant deployment + +You only need one of these options. + +Both options use [ansible](https://docs.ansible.com/) to: + +- setup the Hydra authorization server - setup IDP (provides login and consent screens) - setup demo application -- setup setup OpenID Connect client registration application +- setup OpenID Connect client registration application + +### Local deployment + +Use `ansible-playbook` to deploy Hydra, IDP, Client registration and the demo +application: + +```shell +cd deployment +ansible-playbook 01_install_cacert_oidc.yml +``` + +Note: If ansible-playbook fails early in the process with "sudo: a password is required," +then confirm that your user has sudo privileges and execute the `ansible-playbook` command like: + +```shell +ansible-playbook -K 01_install_cacert_oidc.yml +``` + +### Vagrant setup + +Instead of Ansible, you can also use [Vagrant](https://www.vagrantup.com/) with the +libvirt-provider. The included Vagrantfile is configured to apply the +ansible-playbook to the Vagrant managed virtual machine. + +```shell +sudo apt install vagrant-libvirt virt-manager libvirt-clients +vagrant up +vagrant ssh -- cat .local/share/mkcert/rootCA.pem | sudo tee /usr/local/share/ca-certificates/mkcert-vagrant-oidc.crt +sudo update-ca-certificates +``` + + +======== + +## Finally + +Note: You may also want to configure your browser to trust the CA certificate +in `/usr/local/share/ca-certificates/mkcert-vagrant-oidc.crt`. If you do not +add this trust configuration you will get browser warnings for an unknown +certificate authority. + +## Testing your local setup + +After running "make" and "ansible-playbook," Hydra and oidc-idp will both be running. + +To run the rest of the components, in each of two new terminal windows, execute +"oidc_app/demo-app" and "oidc_registration/cacert-oidc-registration". + + +### Test the authorization server + +Request the OpenID connect auto discovery information from Hydra + +```shell +curl https://hydra.cacert.localhost:4444/.well-known/openid-configuration | python3 -m json.tool +``` + +This should give you a JSON document with information about the authorization server. + +### Test the identity provider + +Open +[https://login.cacert.localhost:3000/](https://login.cacert.localhost:3000/) +this should ask you for a CAcert class 3 client certificate and should render a +404 page with a CAcert logo. + diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..2c41041 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,32 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.configure("2") do |config| + config.vm.box = "debian/bookworm64" + + config.vm.define "oidcbox" + + config.vm.network "forwarded_port", guest: 4444, host: 4444, host_ip: "127.0.0.1" + config.vm.network "forwarded_port", guest: 3000, host: 3000, host_ip: "127.0.0.1" + config.vm.network "forwarded_port", guest: 4000, host: 4000, host_ip: "127.0.0.1" + config.vm.network "forwarded_port", guest: 5000, host: 5000, host_ip: "127.0.0.1" + + config.vm.provider "libvirt" do |lv| + lv.memory = "2048" + lv.cpus = 2 + lv.machine_virtual_size = 10 + lv.memorybacking :access, :mode => "shared" + end + + config.vm.synced_folder "./", "/vagrant", type: "virtiofs" + + config.vm.provision "ansible" do |ansible| + ansible.playbook = "deployment/01_install_cacert_oidc.yml" + ansible.verbose = true + ansible.groups = { + "pgsqlserver" => ["oidcbox"], + "authserver" => ["oidcbox"], + "demoserver" => ["oidcbox"] + } + end +end diff --git a/cacert_resources b/cacert_resources index 5cbcbef..c449873 160000 --- a/cacert_resources +++ b/cacert_resources @@ -1 +1 @@ -Subproject commit 5cbcbefac6f05fa6537b6a925cc29118a5ecc571 +Subproject commit c449873fd1d170a6928733e4a7e90c073499dcc2 diff --git a/deployment/01_install_cacert_oidc.yml b/deployment/01_install_cacert_oidc.yml new file mode 100644 index 0000000..b826065 --- /dev/null +++ b/deployment/01_install_cacert_oidc.yml @@ -0,0 +1,44 @@ +--- +- name: Install development tools + hosts: all + become: false + + roles: + - prepare_devtools + +- name: Setup database + hosts: pgsqlserver + become: true + + pre_tasks: + + - name: Install package python3-psycopg2 + ansible.builtin.apt: + name: python3-psycopg2 + state: present + + # The ACL package is required to run commands as the postgres user + # See https://docs.ansible.com/ansible-core/2.12/user_guide/become.html#risks-of-becoming-an-unprivileged-user + - name: Install package acl + ansible.builtin.apt: + name: acl + state: present + + roles: + - hydra_database + +- name: Install authorization server + hosts: authserver + become: true + + roles: + - hydra_server + - oidc_idp + - oidc_client_registration + +- name: Install demo application + hosts: demoserver + become: true + + roles: + - oidc_demo_application diff --git a/deployment/README.md b/deployment/README.md new file mode 100644 index 0000000..a37907b --- /dev/null +++ b/deployment/README.md @@ -0,0 +1,4 @@ +Deployment automation for the CAcert OIDC setup + +This directory contains [Ansible](https://docs.ansible.com) automation code to +install and setup the CAcert OpenID connect components. diff --git a/deployment/ansible.cfg b/deployment/ansible.cfg new file mode 100644 index 0000000..23c9600 --- /dev/null +++ b/deployment/ansible.cfg @@ -0,0 +1,35 @@ +[defaults] +# (boolean) By default Ansible will issue a warning when received from a task action (module or action plugin) +# These warnings can be silenced by adjusting this setting to False. +action_warnings=True + +# (string) Chooses which cache plugin to use, the default 'memory' is ephemeral. +fact_caching=memory + +# (pathlist) Comma separated list of Ansible inventory sources +inventory=inventory/local + +# (pathspec) Colon separated paths in which Ansible will search for Roles. +roles_path=./roles:~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles + +# (boolean) Toggles the use of persistence for connections. +use_persistent_connections=True + +interpreter_python=auto_silent + + +[privilege_escalation] +# (boolean) Display an agnostic become prompt instead of displaying a prompt containing the command line supplied become method +agnostic_become_prompt=True + +# (boolean) This setting controls if become is skipped when remote user and become user are the same. I.E root sudo to root. +# If executable, it will be run and the resulting stdout will be used as the password. +become_allow_same_user=False + + +[diff] +# (bool) Configuration toggle to tell modules to show differences when in 'changed' status, equivalent to ``--diff``. +always=True + +# (integer) How many lines of context to show when displaying the differences between files. +context=3 diff --git a/deployment/group_vars/all.yml b/deployment/group_vars/all.yml new file mode 100644 index 0000000..1acb311 --- /dev/null +++ b/deployment/group_vars/all.yml @@ -0,0 +1,2 @@ +--- +hydra_home: /srv/hydra diff --git a/deployment/group_vars/authserver.yml b/deployment/group_vars/authserver.yml new file mode 100644 index 0000000..043cada --- /dev/null +++ b/deployment/group_vars/authserver.yml @@ -0,0 +1,40 @@ +--- +# defaults to CAcert class 3 certificate +idp: + client_certificate_data: | + -----BEGIN CERTIFICATE----- + MIIGPTCCBCWgAwIBAgIDFOIoMA0GCSqGSIb3DQEBDQUAMHkxEDAOBgNVBAoTB1Jv + b3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZ + Q0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9y + dEBjYWNlcnQub3JnMB4XDTIxMDQxOTEyMTgzMFoXDTMxMDQxNzEyMTgzMFowVDEU + MBIGA1UEChMLQ0FjZXJ0IEluYy4xHjAcBgNVBAsTFWh0dHA6Ly93d3cuQ0FjZXJ0 + Lm9yZzEcMBoGA1UEAxMTQ0FjZXJ0IENsYXNzIDMgUm9vdDCCAiIwDQYJKoZIhvcN + AQEBBQADggIPADCCAgoCggIBAKtJNRFIfNImflOUz0Op3SjXQiqL84d4GVh8D57a + iX3h++tykA10oZZkq5+gJJlz2uJVdscXe/UErEa4w75/ZI0QbCTzYZzA8pD6Ueb1 + aQFjww9W4kpCz+JEjCUoqMV5CX1GuYrz6fM0KQhF5Byfy5QEHIGoFLOYZcRD7E6C + jQnRvapbjZLQ7N6QxX8KwuPr5jFaXnQ+lzNZ6MMDPWAzv/fRb0fEze5ig1JuLgia + pNkVGJGmhZJHsK5I6223IeyFGmhyNav/8BBdwPSUp2rVO5J+TJAFfpPBLIukjmJ0 + FXFuC3ED6q8VOJrU0gVyb4z5K+taciX5OUbjchs+BMNkJyIQKopPWKcDrb60LhPt + XapI19V91Cp7XPpGBFDkzA5CW4zt2/LP/JaT4NsRNlRiNDiPDGCbO5dWOK3z0luL + oFvqTpa4fNfVoIZwQNORKbeiPK31jLvPGpKK5DR7wNhsX+kKwsOnIJpa3yxdUly6 + R9Wb7yQocDggL9V/KcCyQQNokszgnMyXS0XvOhAKq3A6mJVwrTWx6oUrpByAITGp + rmB6gCZIALgBwJNjVSKRPFbnr9s6JfOPMVTqJouBWfmh0VMRxXudA/Z0EeBtsSw/ + LIaRmXGapneLNGDRFLQsrJ2vjBDTn8Rq+G8T/HNZ92ZCdB6K4/jc0m+YnMtHmJVA + BfvpAgMBAAGjgfIwge8wDwYDVR0TAQH/BAUwAwEB/zBhBggrBgEFBQcBAQRVMFMw + IwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLkNBY2VydC5vcmcvMCwGCCsGAQUFBzAC + hiBodHRwOi8vd3d3LkNBY2VydC5vcmcvY2xhc3MzLmNydDBFBgNVHSAEPjA8MDoG + CysGAQQBgZBKAgMBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cuQ0FjZXJ0Lm9y + Zy9jcHMucGhwMDIGA1UdHwQrMCkwJ6AloCOGIWh0dHBzOi8vd3d3LmNhY2VydC5v + cmcvY2xhc3MzLmNybDANBgkqhkiG9w0BAQ0FAAOCAgEAxh6td1y0KJvRyI1EEsC9 + dnYEgyEH+BGCf2vBlULAOBG1JXCNiwzB1Wz9HBoDfIv4BjGlnd5BKdSLm4TXPcE3 + hnGjH1thKR5dd3278K25FRkTFOY1gP+mGbQ3hZRB6IjDX+CyBqS7+ECpHTms7eo/ + mARN+Yz5R3lzUvXs3zSX+z534NzRg4i6iHNHWqakFcQNcA0PnksTB37vGD75pQGq + eSmx51L6UzrIpn+274mhsaFNL85jhX+lKuk71MGjzwoThbuZ15xmkITnZtRQs6Hh + LSIqJWjDILIrxLqYHehK71xYwrRNhFb3TrsWaEJskrhveM0Os/vvoLNkh/L3iEQ5 + /LnmLMCYJNRALF7I7gsduAJNJrgKGMYvHkt1bo8uIXO8wgNV7qoU4JoaB1ML30QU + qGcFr0TI06FFdgK2fwy5hulPxm6wuxW0v+iAtXYx/mRkwQpYbcVQtrIDvx1CT1k5 + 0cQxi+jIKjkcFWHw3kBoDnCos0/ukegPT7aQnk2AbL4c7nCkuAcEKw1BAlSETkfq + i5btdlhh58MhewZv1LcL5zQyg8w1puclT3wXQvy8VwPGn0J/mGD4gLLZ9rGcHDUE + CokxFoWk+u5MCcVqmGbsyG4q5suS3CNslsHURfM8bQK4oLvHR8LCHEBMRcdFBn87 + cSvOK6eB1kdGKLA8ymXxZp8= + -----END CERTIFICATE----- diff --git a/deployment/host_vars/localhost.yml b/deployment/host_vars/localhost.yml new file mode 100644 index 0000000..297fcfd --- /dev/null +++ b/deployment/host_vars/localhost.yml @@ -0,0 +1,40 @@ +--- +# this is for a localhost deployment, database passwords for public servers +# must be different random values encrypted via ansible-vault +hydra_db_password: hydra +hydra_db_host: localhost +hydra_db_port: 5432 +hydra_tls: + cert: "{{ hydra_home }}/etc/localhost+2.pem" + key: "{{ hydra_home }}/etc/localhost+2-key.pem" +# this is for a localhost deployment, secrets for public servers must be +# different random values encrypted via ansible-vault +hydra_system_secret: "AczA+NZ25Ye9eAreglv5bo9XcND6uwBQHVUYCvPfwXo=" + +register_tls: + cert: "{{ cacert_home }}/etc/register.cacert.localhost.pem" + key: "{{ cacert_home }}/etc/register.cacert.localhost-key.pem" + +demoapp_tls: + cert: "{{ cacert_home }}/etc/app.cacert.localhost.pem" + key: "{{ cacert_home }}/etc/app.cacert.localhost-key.pem" + +oidc_urls: + hydra_admin: + host: hydra.cacert.localhost + port: 4445 + hydra_public: + address: localhost + host: auth.cacert.localhost + port: 4444 + idp: + host: login.cacert.localhost + port: 3000 + demoapp: + host: app.cacert.localhost + port: 4000 + register: + host: register.cacert.localhost + port: 5000 + +use_mkcert: true diff --git a/deployment/host_vars/oidcbox.yml b/deployment/host_vars/oidcbox.yml new file mode 100644 index 0000000..7915152 --- /dev/null +++ b/deployment/host_vars/oidcbox.yml @@ -0,0 +1,39 @@ +--- +# this is for a localhost deployment, database passwords for public servers +# must be different random values encrypted via ansible-vault +hydra_db_password: hydra +hydra_db_host: localhost +hydra_db_port: 5432 +hydra_tls: + cert: "{{ hydra_home }}/etc/localhost+2.pem" + key: "{{ hydra_home }}/etc/localhost+2-key.pem" +# this is for a localhost deployment, secrets for public servers must be +# different random values encrypted via ansible-vault +hydra_system_secret: "AczA+NZ25Ye9eAreglv5bo9XcND6uwBQHVUYCvPfwXo=" + +register_tls: + cert: "{{ cacert_home }}/etc/register.cacert.localhost.pem" + key: "{{ cacert_home }}/etc/register.cacert.localhost-key.pem" + +demoapp_tls: + cert: "{{ cacert_home }}/etc/app.cacert.localhost.pem" + key: "{{ cacert_home }}/etc/app.cacert.localhost-key.pem" + +oidc_urls: + hydra_admin: + host: hydra.cacert.localhost + port: 4445 + hydra_public: + host: auth.cacert.localhost + port: 4444 + idp: + host: login.cacert.localhost + port: 3000 + demoapp: + host: app.cacert.localhost + port: 4000 + register: + host: register.cacert.localhost + port: 5000 + +use_mkcert: true diff --git a/deployment/inventory/local b/deployment/inventory/local new file mode 100644 index 0000000..fcb4ffa --- /dev/null +++ b/deployment/inventory/local @@ -0,0 +1,10 @@ +localhost ansible_connection=local + +[pgsqlserver] +localhost + +[authserver] +localhost + +[demoserver] +localhost diff --git a/deployment/roles/hydra_database/README.md b/deployment/roles/hydra_database/README.md new file mode 100644 index 0000000..38a8f85 --- /dev/null +++ b/deployment/roles/hydra_database/README.md @@ -0,0 +1,38 @@ +Hydra Database +============== + +Setup a PostgreSQL database for [ORY Hydra](https://ory.sh/hydra/). + +Requirements +------------ + +The role expects a Debian system running Debian 11 or later. + +Role Variables +-------------- + +| Name | Description | Default | +| ------------------- | ----------------- | ------- | +| `hydra_db_name` | Database name | `hydra` | +| `hydra_db_user` | Database user | `hydra` | +| `hydra_db_password` | Database password | - | + + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - hydra_database + +License +------- + +GPL-2.0-or-later + +Author Information +------------------ + +Jan Dittberner diff --git a/deployment/roles/hydra_database/defaults/main.yml b/deployment/roles/hydra_database/defaults/main.yml new file mode 100644 index 0000000..a1770a1 --- /dev/null +++ b/deployment/roles/hydra_database/defaults/main.yml @@ -0,0 +1,3 @@ +--- +hydra_db_name: hydra +hydra_db_user: hydra diff --git a/deployment/roles/hydra_database/handlers/main.yml b/deployment/roles/hydra_database/handlers/main.yml new file mode 100644 index 0000000..d8a9d8e --- /dev/null +++ b/deployment/roles/hydra_database/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for hydra_database diff --git a/deployment/roles/hydra_database/meta/main.yml b/deployment/roles/hydra_database/meta/main.yml new file mode 100644 index 0000000..fbaf1a6 --- /dev/null +++ b/deployment/roles/hydra_database/meta/main.yml @@ -0,0 +1,17 @@ +--- +galaxy_info: + author: Jan Dittberner + description: ORY Hydra database setup + company: CAcert + issue_tracker_url: https://code.cacert.org/cacert/oidc-parent/issues + license: GPL-2.0-or-later + min_ansible_version: 2.1 + platforms: + - name: Debian + versions: + - bullseye + - bookworm + + galaxy_tags: [] + +dependencies: [] diff --git a/deployment/roles/hydra_database/tasks/main.yml b/deployment/roles/hydra_database/tasks/main.yml new file mode 100644 index 0000000..c5bc6d3 --- /dev/null +++ b/deployment/roles/hydra_database/tasks/main.yml @@ -0,0 +1,29 @@ +--- +- name: Install PostgreSQL server + ansible.builtin.package: + name: postgresql + state: present + +- name: Create Hydra database + community.postgresql.postgresql_db: + name: "{{ hydra_db_name }}" + encoding: UTF-8 + template: template0 + state: present + become_user: postgres + +- name: Create Hydra database user + community.postgresql.postgresql_user: + name: "{{ hydra_db_user }}" + password: "{{ hydra_db_password }}" + state: present + become_user: postgres + +- name: Grant permissions on Hydra database to Hydra database user + community.postgresql.postgresql_privs: + database: "{{ hydra_db_name }}" + state: present + privs: CREATE,CONNECT + type: database + role: "{{ hydra_db_user }}" + become_user: postgres diff --git a/deployment/roles/hydra_server/README.md b/deployment/roles/hydra_server/README.md new file mode 100644 index 0000000..225dd44 --- /dev/null +++ b/deployment/roles/hydra_server/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/deployment/roles/hydra_server/defaults/main.yml b/deployment/roles/hydra_server/defaults/main.yml new file mode 100644 index 0000000..a1c1c9f --- /dev/null +++ b/deployment/roles/hydra_server/defaults/main.yml @@ -0,0 +1,11 @@ +--- +hydra_db_name: hydra +hydra_db_user: hydra +hydra_os_group: hydra +hydra_os_user: hydra +hydra_home: /srv/hydra + +hydra_version: "1.11.9" +hydra_checksum: "0e38096a45ae411f70b95beaad69a5335a16cf34c4963724beef3ebce37c283c" + +use_mkcert: false diff --git a/deployment/roles/hydra_server/handlers/main.yml b/deployment/roles/hydra_server/handlers/main.yml new file mode 100644 index 0000000..63b31e8 --- /dev/null +++ b/deployment/roles/hydra_server/handlers/main.yml @@ -0,0 +1,7 @@ +--- +- name: hydra_systemd_reload + ansible.builtin.systemd: + state: started + name: hydra + daemon_reload: true + enabled: true diff --git a/deployment/roles/hydra_server/meta/main.yml b/deployment/roles/hydra_server/meta/main.yml new file mode 100644 index 0000000..18848a7 --- /dev/null +++ b/deployment/roles/hydra_server/meta/main.yml @@ -0,0 +1,52 @@ +galaxy_info: + author: Jan Dittberner + description: Setup ORY Hydra server + company: CAcert + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: GPL-2.0-or-later + + min_ansible_version: 2.1 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/deployment/roles/hydra_server/tasks/main.yml b/deployment/roles/hydra_server/tasks/main.yml new file mode 100644 index 0000000..ad1d1df --- /dev/null +++ b/deployment/roles/hydra_server/tasks/main.yml @@ -0,0 +1,130 @@ +--- +- name: Create Hydra group + ansible.builtin.group: + name: "{{ hydra_os_group }}" + state: present + system: true + +- name: Create Hydra user + ansible.builtin.user: + name: "{{ hydra_os_user }}" + group: "{{ hydra_os_group }}" + home: "{{ hydra_home }}" + state: present + system: true + + +- name: Create Hydra directories + ansible.builtin.file: + path: "{{hydra_home }}/{{ item.path }}" + owner: "{{ hydra_os_user }}" + group: "{{ hydra_os_group }}" + mode: "{{ item.mode }}" + state: directory + loop: + - { path: etc, mode: '0750' } + - { path: bin, mode: '0750' } + - { path: download, mode: '0750' } + + +- name: Download Hydra binary + ansible.builtin.get_url: + url: "https://github.com/ory/hydra/releases/download/v{{ hydra_version }}/hydra_{{ hydra_version }}-linux_64bit.tar.gz" + dest: "{{ hydra_home }}/download/hydra_{{ hydra_version }}-linux_64bit.tar.gz" + checksum: "sha256:{{ hydra_checksum }}" + owner: "{{ hydra_os_user }}" + group: "{{ hydra_os_group }}" + mode: '0640' + +- name: Extract Hydra binary + ansible.builtin.unarchive: + remote_src: true + src: "{{ hydra_home }}/download/hydra_{{ hydra_version }}-linux_64bit.tar.gz" + dest: "{{ hydra_home }}/bin" + owner: root + group: "{{ hydra_os_group }}" + include: 'hydra' + mode: '0750' + +- name: Create Hydra configuration + ansible.builtin.template: + src: hydra.yml.j2 + dest: "{{ hydra_home }}/etc/hydra.yml" + owner: root + group: "{{ hydra_os_group }}" + mode: '0640' + notify: hydra_systemd_reload + +- name: Check whether certificate exists + ansible.builtin.stat: + path: "{{ hydra_tls.cert }}" + register: hydra_cert_st + +- name: Create Hydra key and certificate with mkcert + block: + + - name: Create temporary directory for Hydra key and certificate + ansible.builtin.tempfile: + prefix: "hydra-cert." + state: directory + register: hydra_cert_temp_dir + + - name: Create Hydra key and certificate + ansible.builtin.command: + cmd: "mkcert -cert-file {{ hydra_cert_temp_dir.path }}/hydra.pem -key-file {{ hydra_cert_temp_dir.path }}/hydra.key.pem {{ oidc_urls.hydra_admin.host }} {{ oidc_urls.hydra_public.host }}" + + - name: Move Hydra certificate and key to target + ansible.builtin.copy: + src: "{{ hydra_cert_temp_dir.path }}/{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: "{{ hydra_os_group }}" + mode: "{{ item.mode }}" + remote_src: true + loop: + - {src: hydra.pem, dest: "{{ hydra_tls.cert }}", mode: '0644'} + - {src: hydra.key.pem, dest: "{{ hydra_tls.key }}", mode: '0640'} + become: true + + - name: Remove temporary directory + ansible.builtin.file: + path: "{{ hydra_cert_temp_dir.path }}" + state: absent + + when: use_mkcert and not hydra_cert_st.stat.exists + become: false + +- name: Copy Hydra key and certificate from inventory + block: + + - name: Copy Hydra certificate + ansible.builtin.copy: + dest: "{{ hydra_tls.cert }}" + owner: root + group: "{{ hydra_os_group }}" + mode: '0644' + content: "{{ hydra_tls.certdata }}" + + - name: Copy Hydra key + ansible.builtin.copy: + dest: "{{ hydra_tls.key }}" + owner: root + group: "{{ hydra_os_group }}" + mode: '0640' + content: "{{ hydra_tls.keydata }}" + + when: not use_mkcert + +- name: Run Hydra SQL migrations + ansible.builtin.command: + cmd: "{{ hydra_home }}/bin/hydra migrate sql --yes --read-from-env --config {{ hydra_home }}/etc/hydra.yml" + changed_when: false + +- name: Create systemd unit file + ansible.builtin.template: + src: hydra.service.j2 + dest: /etc/systemd/system/hydra.service + owner: root + group: root + mode: "0640" + notify: hydra_systemd_reload diff --git a/deployment/roles/hydra_server/templates/hydra.service.j2 b/deployment/roles/hydra_server/templates/hydra.service.j2 new file mode 100644 index 0000000..92bc507 --- /dev/null +++ b/deployment/roles/hydra_server/templates/hydra.service.j2 @@ -0,0 +1,13 @@ +[Unit] +Description=ORY Hydra OAuth2/OpenID Connect API server +After=network.target +Documentation=https://www.ory.sh/docs/hydra/ + +[Service] +ExecStart={{ hydra_home }}/bin/hydra serve all --config "{{ hydra_home }}/etc/hydra.yml" +WorkingDirectory={{ hydra_home }} +User={{ hydra_os_user }} +Group={{ hydra_os_group }} + +[Install] +WantedBy=multi-user.target diff --git a/deployment/roles/hydra_server/templates/hydra.yml.j2 b/deployment/roles/hydra_server/templates/hydra.yml.j2 new file mode 100644 index 0000000..98c6dbc --- /dev/null +++ b/deployment/roles/hydra_server/templates/hydra.yml.j2 @@ -0,0 +1,48 @@ +--- +serve: + admin: + host: {{ oidc_urls.hydra_admin.address | default("localhost") }} + port: {{ oidc_urls.hydra_admin.port | default("4445") }} + public: + host: {{ oidc_urls.hydra_public.address | default(ansible_default_ipv4.address) }} + port: {{ oidc_urls.hydra_public.port | default("4444") }} + tls: + cert: + path: {{ hydra_tls.cert }} + key: + path: {{ hydra_tls.key }} +dsn: 'postgres://{{ hydra_db_user }}:{{ hydra_db_password }}@{{ hydra_db_host }}:{{ hydra_db_port }}/{{ hydra_db_name }}' + +webfinger: + oidc_discovery: + supported_claims: + - email + - email_verified + - given_name + - family_name + - middle_name + - name + - birthdate + - zoneinfo + - locale + - https://auth.cacert.org/groups + supported_scope: + - profile + - email + +oauth2: + expose_internal_errors: false + +urls: + login: https://{{ oidc_urls.idp.host }}:{{ oidc_urls.idp.port }}/login + consent: https://{{ oidc_urls.idp.host }}:{{ oidc_urls.idp.port }}/consent + logout: https://{{ oidc_urls.idp.host }}:{{ oidc_urls.idp.port }}/logout + error: https://{{ oidc_urls.idp.host }}:{{ oidc_urls.idp.port }}/error + post_logout_redirect: https://{{ oidc_urls.idp.host }}:{{ oidc_urls.idp.port }}/logout-successful + self: + public: https://{{ oidc_urls.hydra_public.host }}:{{ oidc_urls.hydra_public.port }}/ + issuer: https://{{ oidc_urls.hydra_public.host }}:{{ oidc_urls.hydra_public.port }}/ + +secrets: + system: + - "{{ hydra_system_secret }}" diff --git a/deployment/roles/hydra_server/vars/main.yml b/deployment/roles/hydra_server/vars/main.yml new file mode 100644 index 0000000..189ec15 --- /dev/null +++ b/deployment/roles/hydra_server/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for roles/hydra_server diff --git a/deployment/roles/oidc_client_registration/README.md b/deployment/roles/oidc_client_registration/README.md new file mode 100644 index 0000000..225dd44 --- /dev/null +++ b/deployment/roles/oidc_client_registration/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/deployment/roles/oidc_client_registration/defaults/main.yml b/deployment/roles/oidc_client_registration/defaults/main.yml new file mode 100644 index 0000000..ca4b246 --- /dev/null +++ b/deployment/roles/oidc_client_registration/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for roles/oidc_client_registration diff --git a/deployment/roles/oidc_client_registration/handlers/main.yml b/deployment/roles/oidc_client_registration/handlers/main.yml new file mode 100644 index 0000000..f9ded04 --- /dev/null +++ b/deployment/roles/oidc_client_registration/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for roles/oidc_client_registration diff --git a/deployment/roles/oidc_client_registration/meta/main.yml b/deployment/roles/oidc_client_registration/meta/main.yml new file mode 100644 index 0000000..c572acc --- /dev/null +++ b/deployment/roles/oidc_client_registration/meta/main.yml @@ -0,0 +1,52 @@ +galaxy_info: + author: your name + description: your role description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.1 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/deployment/roles/oidc_client_registration/tasks/main.yml b/deployment/roles/oidc_client_registration/tasks/main.yml new file mode 100644 index 0000000..8662f7a --- /dev/null +++ b/deployment/roles/oidc_client_registration/tasks/main.yml @@ -0,0 +1,2 @@ +--- +# tasks file for roles/oidc_client_registration diff --git a/deployment/roles/oidc_client_registration/vars/main.yml b/deployment/roles/oidc_client_registration/vars/main.yml new file mode 100644 index 0000000..188961d --- /dev/null +++ b/deployment/roles/oidc_client_registration/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for roles/oidc_client_registration diff --git a/deployment/roles/oidc_demo_application/README.md b/deployment/roles/oidc_demo_application/README.md new file mode 100644 index 0000000..225dd44 --- /dev/null +++ b/deployment/roles/oidc_demo_application/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/deployment/roles/oidc_demo_application/defaults/main.yml b/deployment/roles/oidc_demo_application/defaults/main.yml new file mode 100644 index 0000000..a344905 --- /dev/null +++ b/deployment/roles/oidc_demo_application/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for roles/oidc_demo_application diff --git a/deployment/roles/oidc_demo_application/handlers/main.yml b/deployment/roles/oidc_demo_application/handlers/main.yml new file mode 100644 index 0000000..29cefff --- /dev/null +++ b/deployment/roles/oidc_demo_application/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for roles/oidc_demo_application diff --git a/deployment/roles/oidc_demo_application/meta/main.yml b/deployment/roles/oidc_demo_application/meta/main.yml new file mode 100644 index 0000000..c572acc --- /dev/null +++ b/deployment/roles/oidc_demo_application/meta/main.yml @@ -0,0 +1,52 @@ +galaxy_info: + author: your name + description: your role description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.1 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/deployment/roles/oidc_demo_application/tasks/main.yml b/deployment/roles/oidc_demo_application/tasks/main.yml new file mode 100644 index 0000000..d02ffeb --- /dev/null +++ b/deployment/roles/oidc_demo_application/tasks/main.yml @@ -0,0 +1,2 @@ +--- +# tasks file for roles/oidc_demo_application diff --git a/deployment/roles/oidc_demo_application/vars/main.yml b/deployment/roles/oidc_demo_application/vars/main.yml new file mode 100644 index 0000000..b973543 --- /dev/null +++ b/deployment/roles/oidc_demo_application/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for roles/oidc_demo_application diff --git a/deployment/roles/oidc_idp/README.md b/deployment/roles/oidc_idp/README.md new file mode 100644 index 0000000..976afdb --- /dev/null +++ b/deployment/roles/oidc_idp/README.md @@ -0,0 +1,19 @@ +Role Name +========= + +Setup the CAcert OpenID Connect identity provider application. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +License +------- + +GPL-2.0-or-later + +Author Information +------------------ + +Jan Dittberner diff --git a/deployment/roles/oidc_idp/defaults/main.yml b/deployment/roles/oidc_idp/defaults/main.yml new file mode 100644 index 0000000..58205fb --- /dev/null +++ b/deployment/roles/oidc_idp/defaults/main.yml @@ -0,0 +1,4 @@ +--- +cacert_os_user: cacert +cacert_os_group: cacert +cacert_home: /srv/cacert diff --git a/deployment/roles/oidc_idp/handlers/main.yml b/deployment/roles/oidc_idp/handlers/main.yml new file mode 100644 index 0000000..0901f0e --- /dev/null +++ b/deployment/roles/oidc_idp/handlers/main.yml @@ -0,0 +1,7 @@ +--- +- name: idp_systemd_reload + ansible.builtin.systemd: + state: started + name: cacert-idp + daemon_reload: true + enabled: true diff --git a/deployment/roles/oidc_idp/meta/main.yml b/deployment/roles/oidc_idp/meta/main.yml new file mode 100644 index 0000000..1f76312 --- /dev/null +++ b/deployment/roles/oidc_idp/meta/main.yml @@ -0,0 +1,17 @@ +--- +galaxy_info: + author: Jan Dittberner + description: CAcert OpenID Connect identity provider application setup + company: CAcert + + license: GPL-2.0-or-later + + min_ansible_version: 2.1 + + platforms: + - name: Debian + versions: + - bullseye + - bookworm + + galaxy_tags: [] diff --git a/deployment/roles/oidc_idp/tasks/main.yml b/deployment/roles/oidc_idp/tasks/main.yml new file mode 100644 index 0000000..202912c --- /dev/null +++ b/deployment/roles/oidc_idp/tasks/main.yml @@ -0,0 +1,120 @@ +--- +- name: Create CAcert group + ansible.builtin.group: + name: "{{ cacert_os_group }}" + state: present + system: true + +- name: Create CAcert user + ansible.builtin.user: + name: "{{ cacert_os_user }}" + group: "{{ cacert_os_group }}" + home: "{{ cacert_home }}" + state: present + system: true + +- name: Create CAcert directories + ansible.builtin.file: + path: "{{ cacert_home }}/{{ item.path }}" + owner: "{{ cacert_os_user }}" + group: "{{ cacert_os_group }}" + mode: "{{ item.mode }}" + state: directory + loop: + - { path: etc, mode: '0750' } + - { path: bin, mode: '0750' } + - { path: download, mode: '0750' } + +- name: Copy IDP binary + ansible.builtin.copy: + src: ../oidc_idp/cacert-idp + dest: "{{ cacert_home }}/bin/cacert-idp" + owner: root + group: "{{ cacert_os_group }}" + mode: "0750" + +- name: Check whether certificate exists + ansible.builtin.stat: + path: "{{ idp_tls.cert }}" + register: idp_cert_st + +- name: Create IDP key and certificate with mkcert + block: + + - name: Create temporary directory for IDP key and certificate + ansible.builtin.tempfile: + prefix: "idp-cert." + state: directory + register: idp_cert_temp_dir + + - name: Create IDP key and certificate + ansible.builtin.command: + cmd: "mkcert -cert-file {{ idp_cert_temp_dir.path }}/idp.pem -key-file {{ idp_cert_temp_dir.path }}/idp.key.pem {{ oidc_urls.idp.host }}" + + - name: Move IDP certificate and key to target + ansible.builtin.copy: + src: "{{ idp_cert_temp_dir.path }}/{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: "{{ cacert_os_group }}" + mode: "{{ item.mode }}" + remote_src: true + loop: + - {src: idp.pem, dest: "{{ idp_tls.cert }}", mode: '0644'} + - {src: idp.key.pem, dest: "{{ idp_tls.key }}", mode: '0640'} + become: true + + - name: Remove temporary directory + ansible.builtin.file: + path: "{{ idp_cert_temp_dir.path }}" + state: absent + + when: use_mkcert and not idp_cert_st.stat.exists + become: false + +- name: Copy IDP key and certificate from inventory + block: + + - name: Copy IDP certificate + ansible.builtin.copy: + dest: "{{ idp_tls.cert }}" + owner: root + group: "{{ cacert_os_group }}" + mode: '0644' + content: "{{ idp.server_certificate_data }}" + + - name: Copy IDP key + ansible.builtin.copy: + dest: "{{ idp_tls.key }}" + owner: root + group: "{{ cacert_os_group }}" + mode: '0640' + content: "{{ idp.server_key_data }}" + + when: not use_mkcert + +- name: Copy client CA certificates + ansible.builtin.copy: + dest: "{{ idp_tls.client_cas }}" + owner: root + group: "{{ cacert_os_group }}" + mode: '0640' + content: "{{ idp.client_certificate_data }}" + +- name: Create IDP configuration + ansible.builtin.template: + src: idp_config.toml.j2 + dest: "{{ cacert_home }}/etc/cacert-idp.toml" + owner: root + group: "{{ cacert_os_group }}" + mode: '0640' + notify: idp_systemd_reload + +- name: Create IDP systemd unit file + ansible.builtin.template: + src: cacert-idp.service.j2 + dest: /etc/systemd/system/cacert-idp.service + owner: root + group: root + mode: "0640" + notify: idp_systemd_reload diff --git a/deployment/roles/oidc_idp/templates/cacert-idp.service.j2 b/deployment/roles/oidc_idp/templates/cacert-idp.service.j2 new file mode 100644 index 0000000..e41f828 --- /dev/null +++ b/deployment/roles/oidc_idp/templates/cacert-idp.service.j2 @@ -0,0 +1,14 @@ +[Unit] +Description=CAcert OpenID Connect identity provider +After=network.target +Documentation=https://code.cacert.org/cacert/oidc-idp + +[Service] +ExecStart={{ cacert_home }}/bin/cacert-idp --conf "{{ cacert_home }}/etc/cacert-idp.toml" +WorkingDirectory={{ cacert_home }} +User={{ cacert_os_user }} +Group={{ cacert_os_group }} + +[Install] +WantedBy=multi-user.target + diff --git a/deployment/roles/oidc_idp/templates/idp_config.toml.j2 b/deployment/roles/oidc_idp/templates/idp_config.toml.j2 new file mode 100644 index 0000000..0283eac --- /dev/null +++ b/deployment/roles/oidc_idp/templates/idp_config.toml.j2 @@ -0,0 +1,12 @@ +[security] +csrf.key = "{{ idp_csrf_key | default(lookup('community.general.random_string', length=32, base64=true)) }}" +client.ca-file = "{{ idp_tls.client_cas }}" + +[server] +name = "{{ oidc_urls.idp.address | default(ansible_default_ipv4.address) }}" +port = {{ oidc_urls.idp.address | default("3000") }} +certificate = "{{ idp_tls.cert }}" +key = "{{ idp_tls.key }}" + +[admin] +url = "https://{{ oidc_urls.hydra_admin.address | default("hydra.cacert.localhost") }}:{{ oidc_urls.hydra_admin.port | default("3000") }}" diff --git a/deployment/roles/oidc_idp/vars/main.yml b/deployment/roles/oidc_idp/vars/main.yml new file mode 100644 index 0000000..0dc4e9f --- /dev/null +++ b/deployment/roles/oidc_idp/vars/main.yml @@ -0,0 +1,5 @@ +--- +idp_tls: + cert: "{{ cacert_home }}/etc/{{ oidc_urls.idp.host }}.pem" + key: "{{ cacert_home }}/etc/{{ oidc_urls.idp.host }}-key.pem" + client_cas: "{{ cacert_home }}/etc/{{ oidc_urls.idp.host }}-client-cas.pem" diff --git a/deployment/roles/prepare_devtools/README.md b/deployment/roles/prepare_devtools/README.md new file mode 100644 index 0000000..f5bee91 --- /dev/null +++ b/deployment/roles/prepare_devtools/README.md @@ -0,0 +1,14 @@ +Role Name +========= + +Prepare development tools for the CAcert OIDC setup. + +License +------- + +GPL-2.0-or-later + +Author Information +------------------ + +Jan Dittberner diff --git a/deployment/roles/prepare_devtools/meta/main.yml b/deployment/roles/prepare_devtools/meta/main.yml new file mode 100644 index 0000000..578ebf2 --- /dev/null +++ b/deployment/roles/prepare_devtools/meta/main.yml @@ -0,0 +1,19 @@ +--- +galaxy_info: + author: Jan Dittberner + description: Prepare development tools for the CAcert OIDC setup. + company: CAcert + + license: GPL-2.0-or-later + + min_ansible_version: 2.1 + + platforms: + - name: Debian + versions: + - bullseye + - bookworm + + galaxy_tags: [] + +dependencies: [] diff --git a/deployment/roles/prepare_devtools/tasks/main.yml b/deployment/roles/prepare_devtools/tasks/main.yml new file mode 100644 index 0000000..b35e34f --- /dev/null +++ b/deployment/roles/prepare_devtools/tasks/main.yml @@ -0,0 +1,17 @@ +--- +- name: Prepare mkcert + block: + + - name: Install mkcert + ansible.builtin.apt: + name: mkcert + update_cache: true + become: true + + - name: Install mkcert CA + ansible.builtin.command: + cmd: "mkcert -install" + changed_when: false + + when: use_mkcert + become: false diff --git a/oidc_app b/oidc_app index c69e8d2..bc35b09 160000 --- a/oidc_app +++ b/oidc_app @@ -1 +1 @@ -Subproject commit c69e8d29805af1ad9abab2e6318f3b1c3b45a557 +Subproject commit bc35b0984f74d5abadfbff37589d1970d0119541 diff --git a/oidc_idp b/oidc_idp index 26447f9..962dd30 160000 --- a/oidc_idp +++ b/oidc_idp @@ -1 +1 @@ -Subproject commit 26447f99c92e346ca5823f84db8822e1988f726d +Subproject commit 962dd30c6ad0a95be112227828af1657a30e294f diff --git a/oidc_registration b/oidc_registration index 0c88fb5..be90065 160000 --- a/oidc_registration +++ b/oidc_registration @@ -1 +1 @@ -Subproject commit 0c88fb544734d07a2d61e87b9084ee6fdc274cff +Subproject commit be9006546dbad89aef476d2096c91b14fad2a3f4