Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Which users are working in which Jira projects?

Daniel Pfeffer
Contributor
July 28, 2026

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

1 answer

3 votes
Nikola Perisic
Community Champion
July 28, 2026

Hi @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()

Suggest an answer

Log in or Sign up to answer
DEPLOYMENT TYPE
CLOUD
PRODUCT PLAN
PREMIUM
PERMISSIONS LEVEL
Product Admin
TAGS
AUG Leaders

Atlassian Community Events