Automatically assign new autocreated realm users to a group

Feb 23, 2022
7
1
8
Belgium
I am currently in the process of automating the deployment of PVE hosts including SSO:
For SSO, these steps include:
  • Creating an OpenID-Connect application and provider in Authtentik.
  • Creating a realm with those Authentik parameters in PVE
  • Creating groups, roles and setting ACL's
But I am blocking on one feature and that is to automatically assign users that stem from the SSO realm to a certain group.
A cronjob would not be sufficient since the users are only created when they try to login for the first time and a cronjob is periodic and not triggered on a certain event.
I found a similar question but this tread has been abandoned.
Has anyone done anything similar to this?
 
I am not quite sure what you mean with the word stem. If you want to automatically create users on user sign-in, the configuration dialogue has a checkbox called "Autocreate Users". If checked, this automatically creates any users that do not exist on PVE but do exist on the Authentik realm.
 
The autocreate users has been enabled for the realm SSO. But I want to automatically assign a user (which comes from the SSO realm) to a certain group when the user logs in for the first time.
 
The autocreate users has been enabled for the realm SSO. But I want to automatically assign a user (which comes from the SSO realm) to a certain group when the user logs in for the first time.
Where must this group exist? On the identity provider's side or on PVE's side?
 
I'm afraid that adding users to groups automatically is not possible. May I ask what it is you are trying to do?
We rollout a couple of PVE hosts per month. All these PVE's are currently only reachable using the root@pam user. Lots of our engineer need to login to these systems regularly and since NIS2 required SSO, I am looking to automate to process of:

  • adding the host to authentik by creating a provider and application etc.
  • Creating local groups, SSO Realm and permissions on PVE to define admin and engineers groups
  • Update the redirect IP of the PVE host in authentik through the zabbix and authentik API's so when a server is deployed in the field it gets a new IP address and is thereby automatically updated in authentik.
  • Then finally when the user logs on the PVE host using SSO, it has no permissions since the user is not a member of any group.
I am currently looking to write a script using the `inotify-tools` package to monitor the `/etc/pve/user.cfg` file for changes and then add the user to the correct group. When the script is fine tuned and working I will post it here for those interested.
 
For those interested, I got it working!
Run this script as a system service so it can watch the /etc/pve/user.cfg file:
Bash:
#!/bin/bash

# Configuration
PROXMOX_REALM="SSO"
DEFAULT_GROUP="Engineers"  # Default group for normal users
SPECIAL_GROUP="Sysadmins"  # Group for specific users
USER_CONF_FILE="/etc/pve/user.cfg"
LOG_FILE="/var/log/proxmox_user_add.log"

# Define a static list of users and their target groups
declare -A STATIC_USERS
STATIC_USERS=(
    ["admin1@SSO"]="$SPECIAL_GROUP"
    ["admin2@SSO"]="$SPECIAL_GROUP"
    ["admin3@SSO"]="$SPECIAL_GROUP"
)

# Function to get users from /etc/pve/user.cfg
get_users_from_realm() {
    grep "@$PROXMOX_REALM" "$USER_CONF_FILE" | cut -d':' -f2
}

# Function to check if the user is already a member of the group
is_user_in_group() {
    local user=$1
    local group=$2
    # Check if the user is in the group by searching /etc/pve/user.cfg
    grep -q "group:$group:.*$user" "$USER_CONF_FILE"
}

# Function to add user to a Proxmox group
add_user_to_group() {
    local user=$1
    local group=$2

    if ! is_user_in_group "$user" "$group"; then
        if [[ -n "$user" && -n "$group" ]]; then
            echo "$(date '+%Y-%m-%d %H:%M:%S') - Adding $user to group $group" | tee -a "$LOG_FILE"
            pveum usermod "$user" -group "$group"
        else
            echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: Invalid user or group for $user" | tee -a "$LOG_FILE"
        fi
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') - $user is already a member of $group, skipping." | tee -a "$LOG_FILE"
    fi
}

# Watch for changes in /etc/pve/user.cfg
watch_user_file() {
    echo "Watching for changes in $USER_CONF_FILE..."
    local last_mod_time=$(stat -c %Y "$USER_CONF_FILE")

    while true; do
        sleep 2  # Check every 2 seconds
        local new_mod_time=$(stat -c %Y "$USER_CONF_FILE")

        if [[ $new_mod_time -ne $last_mod_time ]]; then
            echo "$(date '+%Y-%m-%d %H:%M:%S') - Detected change in $USER_CONF_FILE" | tee -a "$LOG_FILE"
            last_mod_time=$new_mod_time

            # Get users from file
            users=$(get_users_from_realm)

            for user in $users; do
                if [[ "$user" == *@${PROXMOX_REALM} ]]; then
                    if [[ -n "${STATIC_USERS[$user]}" ]]; then
                        target_group="${STATIC_USERS[$user]}"
                    else
                        target_group="$DEFAULT_GROUP"
                    fi

                    echo "$(date '+%Y-%m-%d %H:%M:%S') - Processing user $user, assigning group: $target_group" | tee -a "$LOG_FILE"
                    add_user_to_group "$user" "$target_group"
                fi
            done
        fi
    done
}

# Start monitoring
watch_user_file
 
  • Like
Reactions: aabraham