Forums

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

How can fields be configured as read-only based on the status with forge

Rosalin kandapan
February 4, 2026

Question1
With forge
If story (issueType) status is "Done" then can we make Description field Readonly

Question 2
With forge
Can fields be protected allowing editing only by specific roles?
Example: Only Product Managers are allowed to change a certain field in Features

2 answers

0 votes
Nikola Perisic
Community Champion
February 4, 2026

Welcome @Rosalin kandapan 

With Forge, no, with ScriptRunner behaviors this can be done for both use cases.

Rosalin kandapan
February 4, 2026

@Nikola Perisic 
ScriptRunner Marketplace App  i need to use or need to install ScriptRunner

Nikola Perisic
Community Champion
February 4, 2026

@Rosalin kandapan 

ScriptRunner needs to be installed from the Atlassian Marketplace.

For first use case, you would use Behaviours. Behaviour needs to happen when there is a change to the field. The script for the Q1:

/**

* ScriptRunner Cloud Behaviour

* If issueType = Story AND status = Done → Description read-only

*/

const context = await getContext();

const description = getFieldById("description");

let makeReadOnly = false;

// 1️⃣ Check issue type

const issueTypeName = context.extension?.issueType?.name;

if (issueTypeName === "Story") {

// 2️⃣ Only issue view / transition view has an issue key

const issueKey = context.extension?.issue?.key;

if (issueKey) {

// 3️⃣ Load issue to read status

const issueRes = await makeRequest(`/rest/api/3/issue/${issueKey}`);

if (issueRes.status === 200) {

const statusName = issueRes.body?.fields?.status?.name;

if (statusName === "Done") {

makeReadOnly = true;

}

} else {

logger.warn(`Failed to load issue ${issueKey}, status=${issueRes.status}`);

}

}

}

// 4️⃣ Apply UI behaviour

description.setReadOnly(makeReadOnly);

if (makeReadOnly) {

description.setDescription("Locked because this Story is Done.");

} else {

description.setDescription("");

}

Script for the second question:

/**
* ScriptRunner Cloud Behaviour
* Field editable ONLY for users in project role "Product Managers"
* NO top-level return statements (Cloud-safe)
*/

const FIELD_ID = "customfield_12345"; // <-- change me
const ROLE_NAME = "Product Managers"; // <-- project role name

const context = await getContext();
const field = getFieldById(FIELD_ID);

// Default: lock the field
let editable = false;

// Required context
const accountId = context.accountId;
const projectKey = context.extension?.project?.key;

// Proceed only if we have enough context
if (accountId && projectKey) {

// 1️⃣ Get all roles for the project (roleName → roleUrl)
const rolesRes = await makeRequest(`/rest/api/3/project/${projectKey}/role`);

if (rolesRes.status === 200) {
const roleUrl = rolesRes.body?.[ROLE_NAME];

if (roleUrl) {

// Convert full URL → relative path if needed
const rolePath = roleUrl.startsWith("http")
? new URL(roleUrl).pathname + new URL(roleUrl).search
: roleUrl;

// 2️⃣ Load role details (actors)
const roleRes = await makeRequest(rolePath);

if (roleRes.status === 200) {
const actors = roleRes.body?.actors ?? [];

// Direct user assignment
const directUser = actors.some(
(a: any) => a?.actorUser?.accountId === accountId
);

if (directUser) {
editable = true;
} else {

// 3️⃣ Group-based role membership
const roleGroups = actors
.map((a: any) => a?.actorGroup?.name)
.filter(Boolean);

if (roleGroups.length > 0) {

const groupsRes = await makeRequest(
`/rest/api/3/user/groups?accountId=${encodeURIComponent(accountId)}`
);

if (groupsRes.status === 200) {
const userGroups = (groupsRes.body ?? []).map(
(g: any) => g.name
);

editable = roleGroups.some(
(g: string) => userGroups.includes(g)
);
}
}
}
}
}
}
}

// Apply behaviour
field.setReadOnly(!editable);

field.setDescription(
editable
? ""
: `Only users in the "${ROLE_NAME}" role can edit this field.`
);

To get the custom field ID, you need to go to Settings -> Fields and find your field. Then click on three dots and choose Context and default values. In your URL at the very end you will see id parameter, that is your custom field ID.

0 votes
Staffan Redelius
Community Champion
February 4, 2026

Hi @Rosalin kandapan and welcome to the community.

You can reslove Question1 and Question2 by settings properties in the workflow but I doesn't seem to be possible via Forge (yet). There is a feature request for this here that you can vote for.

https://jira.atlassian.com/browse/ECO-846 

Best regards,
/Staffan 

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events