Access Control - FreshPerf/PVE4J GitHub Wiki

Access Control

This guide covers user, group, role, and permission management in PVE4J.

Table of Contents

User Management

List All Users

import fr.freshperf.pve4j.entities.access.PveAccessUser;
import java.util.List;

try {
    List<PveAccessUser> users = proxmox.getAccess()
            .getUsers()
            .getIndex()
            .execute();
    
    for (PveAccessUser user : users) {
        System.out.println("User ID: " + user.getUserid());
        System.out.println("First Name: " + user.getFirstname());
        System.out.println("Last Name: " + user.getLastname());
        System.out.println("Email: " + user.getEmail());
        System.out.println("Enabled: " + user.getEnable());
        System.out.println("Groups: " + user.getGroups());
        System.out.println("---");
    }
} catch (ProxmoxAPIError | InterruptedException e) {
    e.printStackTrace();
}

Get Specific User

try {
    PveAccessUser user = proxmox.getAccess()
            .getUsers()
            .get("root@pam")
            .execute();
    
    System.out.println("User: " + user.getUserid());
    System.out.println("Name: " + user.getFirstname() + " " + user.getLastname());
    System.out.println("Email: " + user.getEmail());
    System.out.println("Comment: " + user.getComment());
} catch (ProxmoxAPIError | InterruptedException e) {
    e.printStackTrace();
}

Group Management

List All Groups

import fr.freshperf.pve4j.entities.access.PveAccessGroup;
import java.util.List;

try {
    List<PveAccessGroup> groups = proxmox.getAccess()
            .getGroups()
            .getIndex()
            .execute();
    
    for (PveAccessGroup group : groups) {
        System.out.println("Group ID: " + group.getGroupid());
        System.out.println("Comment: " + group.getComment());
        System.out.println("Users: " + group.getUsers());
        System.out.println("---");
    }
} catch (ProxmoxAPIError | InterruptedException e) {
    e.printStackTrace();
}

Get Specific Group

try {
    PveAccessGroup group = proxmox.getAccess()
            .getGroups()
            .get("admins")
            .execute();
    
    System.out.println("Group: " + group.getGroupid());
    System.out.println("Members: " + group.getUsers());
    System.out.println("Comment: " + group.getComment());
} catch (ProxmoxAPIError | InterruptedException e) {
    e.printStackTrace();
}

Role Management

List All Roles

import fr.freshperf.pve4j.entities.access.PveAccessRole;
import java.util.List;

try {
    List<PveAccessRole> roles = proxmox.getAccess()
            .getRoles()
            .getIndex()
            .execute();
    
    for (PveAccessRole role : roles) {
        System.out.println("Role ID: " + role.getRoleid());
        System.out.println("Special: " + role.getSpecial());
        System.out.println("Privileges: " + role.getPrivs());
        System.out.println("---");
    }
} catch (ProxmoxAPIError | InterruptedException e) {
    e.printStackTrace();
}

Get Specific Role

try {
    PveAccessRole role = proxmox.getAccess()
            .getRoles()
            .get("Administrator")
            .execute();
    
    System.out.println("Role: " + role.getRoleid());
    System.out.println("Privileges: " + role.getPrivs());
} catch (ProxmoxAPIError | InterruptedException e) {
    e.printStackTrace();
}

Access Control Lists

List ACL Entries

import fr.freshperf.pve4j.entities.access.PveAccessAcl;
import java.util.List;

try {
    List<PveAccessAcl> acls = proxmox.getAccess()
            .getAcl()
            .execute();
    
    for (PveAccessAcl acl : acls) {
        System.out.println("Path: " + acl.getPath());
        System.out.println("Type: " + acl.getType());
        System.out.println("User/Group ID: " + acl.getUgid());
        System.out.println("Role ID: " + acl.getRoleid());
        System.out.println("Propagate: " + acl.getPropagate());
        System.out.println("---");
    }
} catch (ProxmoxAPIError | InterruptedException e) {
    e.printStackTrace();
}

Find ACL Entries for Specific Path

public List<PveAccessAcl> getAclForPath(Proxmox proxmox, String path) 
        throws ProxmoxAPIError, InterruptedException {
    
    List<PveAccessAcl> allAcls = proxmox.getAccess()
            .getAcl()
            .execute();
    
    return allAcls.stream()
            .filter(acl -> path.equals(acl.getPath()))
            .collect(Collectors.toList());
}

// Usage
List<PveAccessAcl> vmAcls = getAclForPath(proxmox, "/vms/100");

Find ACL Entries for Specific User

public List<PveAccessAcl> getAclForUser(Proxmox proxmox, String userid) 
        throws ProxmoxAPIError, InterruptedException {
    
    List<PveAccessAcl> allAcls = proxmox.getAccess()
            .getAcl()
            .execute();
    
    return allAcls.stream()
            .filter(acl -> "user".equals(acl.getType()))
            .filter(acl -> userid.equals(acl.getUgid()))
            .collect(Collectors.toList());
}

Authentication Domains

List Authentication Domains

import fr.freshperf.pve4j.entities.access.PveAccessDomain;
import java.util.List;

try {
    List<PveAccessDomain> domains = proxmox.getAccess()
            .getDomains()
            .execute();
    
    for (PveAccessDomain domain : domains) {
        System.out.println("Realm: " + domain.getRealm());
        System.out.println("Type: " + domain.getType());
        System.out.println("Comment: " + domain.getComment());
        System.out.println("Default: " + domain.getDefaultRealm());
        System.out.println("---");
    }
} catch (ProxmoxAPIError | InterruptedException e) {
    e.printStackTrace();
}

Get a Specific Domain

try {
    JsonElement domain = proxmox.getAccess()
            .getDomain("pam")
            .execute();
    
    System.out.println("Domain details: " + domain);
} catch (ProxmoxAPIError | InterruptedException e) {
    e.printStackTrace();
}

Get Access Index

import fr.freshperf.pve4j.entities.access.PveAccessIndex;

try {
    List<PveAccessIndex> index = proxmox.getAccess()
            .getIndex()
            .execute();
    
    for (PveAccessIndex item : index) {
        System.out.println("Available endpoint: " + item.getSubdir());
    }
} catch (ProxmoxAPIError | InterruptedException e) {
    e.printStackTrace();
}

Get Authentication Ticket

For username/password authentication (alternative to API tokens):

import fr.freshperf.pve4j.entities.access.PveAccessTicket;

try {
    PveAccessTicket ticket = proxmox.getAccess()
            .getTicket("root", "password123", "pam")
            .execute();
    
    System.out.println("Ticket: " + ticket.getTicket());
    System.out.println("CSRF Token: " + ticket.getCSRFPreventionToken());
    System.out.println("Username: " + ticket.getUsername());
} catch (ProxmoxAPIError | InterruptedException e) {
    System.err.println("Authentication failed: " + e.getMessage());
}

Permission Checking

Check User Permissions

public class PermissionChecker {
    
    public boolean hasVMAccess(Proxmox proxmox, String userid, int vmid) {
        try {
            List<PveAccessAcl> acls = proxmox.getAccess()
                    .getAcl()
                    .execute();
            
            String vmPath = "/vms/" + vmid;
            
            return acls.stream()
                    .filter(acl -> vmPath.equals(acl.getPath()))
                    .filter(acl -> "user".equals(acl.getType()))
                    .filter(acl -> userid.equals(acl.getUgid()))
                    .anyMatch(acl -> acl.getRoleid() != null);
            
        } catch (Exception e) {
            return false;
        }
    }
    
    public List<String> getUserRoles(Proxmox proxmox, String userid, String path) {
        try {
            List<PveAccessAcl> acls = proxmox.getAccess()
                    .getAcl()
                    .execute();
            
            return acls.stream()
                    .filter(acl -> path.equals(acl.getPath()))
                    .filter(acl -> "user".equals(acl.getType()))
                    .filter(acl -> userid.equals(acl.getUgid()))
                    .map(PveAccessAcl::getRoleid)
                    .collect(Collectors.toList());
            
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }
}

List Users with Specific Role

public List<String> getUsersWithRole(Proxmox proxmox, String roleid) 
        throws ProxmoxAPIError, InterruptedException {
    
    List<PveAccessAcl> acls = proxmox.getAccess()
            .getAcl()
            .execute();
    
    return acls.stream()
            .filter(acl -> "user".equals(acl.getType()))
            .filter(acl -> roleid.equals(acl.getRoleid()))
            .map(PveAccessAcl::getUgid)
            .distinct()
            .collect(Collectors.toList());
}

List Groups for User

public List<String> getUserGroups(Proxmox proxmox, String userid) 
        throws ProxmoxAPIError, InterruptedException {
    
    PveAccessUser user = proxmox.getAccess()
            .getUsers()
            .get(userid)
            .execute();
    
    String groupsStr = user.getGroups();
    if (groupsStr == null || groupsStr.isEmpty()) {
        return Collections.emptyList();
    }
    
    return Arrays.asList(groupsStr.split(","));
}

Access Control Reports

Generate User Report

public class AccessReporter {
    
    public void generateUserReport(Proxmox proxmox) {
        try {
            List<PveAccessUser> users = proxmox.getAccess()
                    .getUsers()
                    .getIndex()
                    .execute();
            
            List<PveAccessAcl> acls = proxmox.getAccess()
                    .getAcl()
                    .execute();
            
            System.out.println("=== User Report ===\n");
            
            for (PveAccessUser user : users) {
                System.out.println("User: " + user.getUserid());
                System.out.println("Name: " + user.getFirstname() + " " + user.getLastname());
                System.out.println("Enabled: " + user.getEnable());
                
                long aclCount = acls.stream()
                        .filter(acl -> "user".equals(acl.getType()))
                        .filter(acl -> user.getUserid().equals(acl.getUgid()))
                        .count();
                
                System.out.println("ACL Entries: " + aclCount);
                System.out.println("---\n");
            }
            
        } catch (ProxmoxAPIError | InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    public void generateRoleReport(Proxmox proxmox) {
        try {
            List<PveAccessRole> roles = proxmox.getAccess()
                    .getRoles()
                    .getIndex()
                    .execute();
            
            List<PveAccessAcl> acls = proxmox.getAccess()
                    .getAcl()
                    .execute();
            
            System.out.println("=== Role Usage Report ===\n");
            
            for (PveAccessRole role : roles) {
                long usageCount = acls.stream()
                        .filter(acl -> role.getRoleid().equals(acl.getRoleid()))
                        .count();
                
                System.out.println("Role: " + role.getRoleid());
                System.out.println("Privileges: " + role.getPrivs());
                System.out.println("Usage Count: " + usageCount);
                System.out.println("---\n");
            }
            
        } catch (ProxmoxAPIError | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Next Steps

⚠️ **GitHub.com Fallback** ⚠️