Hi Jira Community
I need a simple overview that shows me which active users (internal and external) have access to which Jira spaces. How do I do that? Even after trying various methods with “Rovo,” I haven't been able to achieve the desired result.
I look forward to your suggestions.
Thank you very much
CRB, Daniel Pfeffer
You can use Python for this where it will export users and projects they belong to into CSV.
You will need your API token that you can get through Account Settings -> Security -> API
Script:
import csv
import sys
import requests
from requests.auth import HTTPBasicAuth
# ==========================================
# CONFIGURATION
# ==========================================
JIRA_URL = "" # Replace with your Jira domain
EMAIL = "" # Your Jira login email
API_TOKEN = "" # Generated from https://id.atlassian.com/manage-profile/security/api-tokens
def get_all_projects(auth):
"""Fetches all visible projects in Jira."""
url = f"{JIRA_URL}/rest/api/3/project"
response = requests.get(url, auth=auth, headers={"Accept": "application/json"})
if response.status_code != 200:
print(f"Error fetching projects: {response.status_code} - {response.text}")
sys.exit(1)
return response.json()
def get_project_access_map(auth):
"""
Iterates through projects and roles to build a mapping of:
Active User -> List of Accessible Projects
"""
projects = get_all_projects(auth)
print(f"Found {len(projects)} projects. Mapping user permissions...\n")
# Mapping structure: { "User Display Name (email)": set("Project Key 1", "Project Key 2") }
user_project_map = {}
for project in projects:
project_key = project.get("key")
project_name = project.get("name")
print(f"Processing project: {project_key} ({project_name})...")
# Get all defined roles for this project
roles_url = f"{JIRA_URL}/rest/api/3/project/{project_key}/role"
roles_resp = requests.get(roles_url, auth=auth, headers={"Accept": "application/json"})
if roles_resp.status_code != 200:
continue
roles = roles_resp.json()
for role_name, role_url in roles.items():
# Get detailed membership data for each role
role_detail_resp = requests.get(role_url, auth=auth, headers={"Accept": "application/json"})
if role_detail_resp.status_code != 200:
continue
role_data = role_detail_resp.json()
# Inspect actors (users/groups) assigned to this role
for actor in role_data.get("actors", []):
# Direct user assignment
if actor.get("type") == "atlassian-user-role-actor":
user_data = actor.get("actorUser", {})
# Only include active users
if user_data.get("active", False):
user_id = f"{user_data.get('displayName')} ({user_data.get('emailAddress', 'No Public Email')})"
user_project_map.setdefault(user_id, set()).add(f"{project_name} [{project_key}]")
# Group assignment (resolves group members)
elif actor.get("type") == "atlassian-group-role-actor":
group_name = actor.get("name")
group_users_url = f"{JIRA_URL}/rest/api/3/group/member?groupname={group_name}"
group_resp = requests.get(group_users_url, auth=auth, headers={"Accept": "application/json"})
if group_resp.status_code == 200:
for user in group_resp.json().get("values", []):
if user.get("active", False):
user_id = f"{user.get('displayName')} ({user.get('emailAddress', 'No Public Email')})"
user_project_map.setdefault(user_id, set()).add(f"{project_name} [{project_key}]")
return user_project_map
def main():
auth = HTTPBasicAuth(EMAIL, API_TOKEN)
access_data = get_project_access_map(auth)
print("\n" + "=" * 60)
print("ACTIVE USER PROJECT ACCESS REPORT")
print("=" * 60)
# Print to console
for user, projects in sorted(access_data.items()):
print(f"\nUser: {user}")
print("Accessible Projects:")
for proj in sorted(projects):
print(f" - {proj}")
# Export to CSV
csv_file = "jira_user_project_access.csv"
with open(csv_file, mode="w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["User Info", "Project Count", "Projects"])
for user, projects in sorted(access_data.items()):
writer.writerow([user, len(projects), ", ".join(sorted(projects))])
print(f"\nReport exported successfully to '{csv_file}'!")
if __name__ == "__main__":
main()
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.