Contextra Secure Field
Setup & usage documentation

Everything needed to create the fields, configure who can see what, and validate the permission model end to end.

1. Overview

Contextra Secure Field adds an encrypted, permission-gated custom field to Jira issues, for values that shouldn’t be readable by everyone who can view the issue — passwords, API keys, tokens, and similar secrets. A matching Secure Attachment field type does the same for a small file instead of a short value.

The core guarantee: the raw value is never the field’s own Jira-visible data. An ordinary Jira custom field stores its value in the clear, where anyone with issue-view permission can read it through Jira’s own REST API — regardless of what the field’s own UI shows or hides. Secure Field stores only a non-reversible marker in that slot and keeps the encrypted value in Forge’s own storage, reachable only through this app’s own permission-checked resolver.

At a glance

HostingJira Cloud — Software and Service Management. There is no Server or Data Center version.
VendorContextra Labs
Built withAtlassian Forge, UI Kit
Appears onIssue view and JSM portal request/view screens. Not on the issue-create screen — see section 13 for why.
EncryptionAES-256-GCM, server-side only — the browser never encrypts or decrypts
Data residencyNo external domains declared for the core product. Encrypted values, configuration and the audit log all live in Forge’s own storage, operated by Atlassian, not a third party

A brand-new field’s allow-list is empty by design. Deny-by- default means nobody — including a site admin — can reveal or edit the value until you explicitly configure who can. See section 6 before asking anyone to use the field.

2. Prerequisites

RequirementWhy
Jira Cloud (Software or Service Management) The app is a Forge app and runs on Cloud only.
An active licence or evaluation Without one, saving and revealing a value is blocked. Values already stored remain encrypted in place — an inactive licence never decrypts, exposes, or deletes anything.
Jira admin access Needed once, to create the custom field, add it to screens/contexts/work types, and configure its allow-list.
A place on the field’s allow-list Needed day to day, to reveal or edit the value — this app’s own permission check, independent of ordinary Jira issue-edit permission.

3. Installation

  1. Open the app’s listing on the Atlassian Marketplace.
  2. Click Try it free (or Get it now) and choose the Jira site to install on.
  3. Confirm the requested permissions. They are listed in full in section 5.
  4. Wait for the install to complete. Nothing appears on any issue yet — the field itself does not exist until you create one, and its allow-list is empty until you configure it. See section 4.

4. Creating the Fields

Installing the app adds two new custom field types to Jira — it does not add a field to any issue by itself, and a newly created field cannot be used by anyone until its allow-list is set.

Create the field

Jira Settings (the gear icon) → Issues → Custom fields → Create custom field. Search for Contextra Secure Field (for a text/password-style value) or Contextra Secure Attachment (for a small protected file), name it, and create it.

Classic projects: field scheme and screen

Add the new field to a Field Scheme used by your project, and to a Screen used by the issue types you want it on — the same chain any classic-project custom field goes through.

Team-managed projects: the project’s own field list

Team-managed projects keep a separate field list. Go to Project settings → Fields → Add field and add the field there too — creating it site-wide is not enough on its own.

Team-managed projects: each work type’s layout

Project settings → Work types → [the issue type] → drag the field into the Description fields area, then Save. Repeat for every work type that should show the field.

Configure the field’s allow-list before anyone uses it

A brand-new field’s allow-list is empty by design — nobody can reveal or edit it, not even a site admin, until you explicitly add someone. Open the field’s own configuration screen (see below for exactly how to reach it) and add at least one entry before asking anyone to use the field.

Skipping either team-managed step (3 or 4) leaves the field entirely invisible on issues of that type, with no error message anywhere. If a field you created does not appear on an issue, check the project’s own field list and that specific work type’s layout before assuming something is broken.

Reaching the field’s own configuration screen

This is the one step that is easy to get lost in, because it is not linked from the issue itself:

  1. Jira Settings → Issues → Custom fields.
  2. Find the field, click its … menu, and choose Contexts and default value.
  3. Click Create, edit or delete contexts.
  4. On the page that opens, find Custom field config and click Edit custom field config.

That last click opens the app’s own configuration screen — the allow-lists, second-factor toggle, auto-expiry, BYOK option, and the migration wizard all live there. It is the same screen for both field types.

5. Permissions

The app requests five scopes, and no others:

ScopeWhy it is needed
read:jira-work Resolve the issue's assignee, reporter, creator, project and project lead for allow-list decisions
read:jira-user Resolve the calling user's group and project-role membership for the same allow-list checks
write:jira-work Not granular — required because writing the field's own {v, hasValue, updatedAt} marker (and clearing a migrated original field) goes through a legacy issue-update endpoint not fully covered by a narrower scope
read:servicedesk-request Resolve JSM request-participant membership, for the "Allow JSM request participants" allow-list option
storage:app Store the encrypted value, per-field configuration, and the audit log, via Forge's own key-value store

Four of five scopes are granular. write:jira-work is the one exception, and it is a platform gap rather than a design choice — the endpoint this app must use to write its own Jira-visible marker (and to clear a migrated field’s original value) is not yet fully covered by a narrower scope on its own.

Every check is re-derived from Jira, never trusted from the client

Reveal and edit permission are re-checked against Jira’s own APIs on every single request — who the calling user actually is, and whether they match the field’s allow-list, is never taken as given from anything the browser sends. This closes the standard risk of a client simply claiming a permission it doesn’t have.

Runs on Atlassian

The core product declares no external domains and makes no network request to any third party. The encrypted value, per-field configuration, and the audit log all live in Forge’s own storage — operated by Atlassian on the app’s behalf, not a service Contextra Labs runs.

6. Configuration

Open the field’s configuration screen (see section 4). Configuration is per field.

Who can reveal this field’s value?

Deny-by-default: an empty list means nobody can reveal or edit the value, not even a site admin. Add one or more entries of any of these types:

Entry typeMatches
A specific user By Atlassian account id.
A group By group id.
A project role By role id.
Assignee Whoever the issue is currently assigned to.
Reporter Whoever reported the issue.
Creator Whoever originally created the issue.
Project lead The project's configured lead.
JSM request participants Everyone listed as a participant on the request, for JSM-connected issues.

The same list governs both reveal and edit — there is currently no way to let someone set a value without also being able to see it.

Who can view this field’s audit log?

A separate allow-list, of the same entry types, independent of who can reveal the value itself. This lets you grant a project lead or auditor visibility into who accessed the field, without also granting them the ability to see the secret.

Security options

Require a second factor before reveal — a toggle. See section 8.

Bring your own encryption key (irreversible if the key is lost) — a checkbox, worded exactly this bluntly on the screen itself. See section 9.

Auto-expire after N hours (blank = never) — a text field. See section 9.

Panel wording, reproduced — not a screenshot.

Migrate from an existing plain field

A separate section further down the same screen. See section 10 for the full two-phase walkthrough.

Click Save configuration to apply changes. There is no separate confirmation step for allow-list or security-option changes — only the migration wizard’s clear step requires one, because only that step is irreversible.

7. Setting & Revealing a Value

On an issue carrying the field, anyone on the allow-list sees an input box and a Save button if no value is set yet, or a masked •••••••• with a Reveal button and a Change value option if one is.

  1. Type the value and click Save. It is encrypted before it ever leaves the resolver — the field immediately shows the masked form.
  2. Click Reveal to decrypt and display the value. The app re-checks your permission against Jira at this exact moment, not just when the page loaded.
  3. Click Change value to overwrite it — the same allow-list gates this as revealing does.

What someone outside the allow-list sees

You don't have permission to view this value.

Panel wording, reproduced — not a screenshot.

Deliberately generic — it never hints at who is allowed, to avoid leaking the allow-list itself to someone who isn’t on it. Every denied attempt is written to the audit log regardless.

If the licence or evaluation is inactive, reveal and save are both blocked with “An active licence is required for this action.” The stored, encrypted value is unaffected either way.

8. Two-Factor Confirmation & Audit Log

Two-factor confirmation

When enabled for a field (section 6), clicking Reveal issues a one-time verification code and shows a code-entry box instead of the value immediately:

Verification required. A verification code has been issued. Enter it to reveal this value.

Panel wording, reproduced — not a screenshot.

Enter the code and click Confirm — on success the value reveals automatically in the same action. This gate is real and enforced server-side; see the limitation on delivery in section 13 before relying on it for a live rollout.

Audit log

A View audit log button appears below the field’s value on every reveal-capable surface. Anyone on the field’s separate audit allow-list (section 6) sees a chronological list of entries, each formatted as timestamp, action, and the account that triggered it. Recorded actions include:

ActionWhen it’s logged
value-savedA value is set or changed
reveal-successA value is successfully revealed
reveal-deniedReveal was attempted by someone not on the allow-list, or decryption genuinely failed
edit-deniedSave was attempted by someone not on the allow-list
value-expiredA reveal found the value past its configured TTL, or otherwise gone
config-changedThe field’s configuration was saved
migration-copied / migration-original-cleared / migration-deniedMigration wizard events — see section 10

The log is append-only — there is no way, in this app, to edit or delete an existing entry.

9. Auto-Expiry & Bring Your Own Key

Auto-expire after N hours

Leave blank for a value that never expires, or enter a number of hours. Once a revealed value is past that age, the field clears itself and reports:

This value has expired.

Panel wording, reproduced — not a screenshot.

An expired value is genuinely gone — there is no way to recover it once its TTL has passed, by design. If you change a field’s TTL after a value was already saved under a shorter one, the value can expire earlier than the field’s current setting suggests; this is disclosed behaviour, not a bug, and is reported the same way as an ordinary expiry, never as a decryption error.

Bring your own encryption key

An optional checkbox, worded on the screen itself exactly as bluntly as it should be: “Bring your own encryption key (irreversible if the key is lost).”

There is no recovery path for a lost BYOK key. Enable this only if your organization can guarantee the key’s own custody — a lost key means every value encrypted under it is permanently undecryptable.

10. Migrating an Existing Plain Field

If you already have a plain Jira field holding values that should have been encrypted from the start, the migration wizard — on the same configuration screen, below Security options — copies them in, in two clearly separated phases.

Phase 1 — copy (never moves)

  1. Enter the source field id (for example customfield_10001) — the plain field you’re migrating from.
  2. Enter one or more issue keys or ids, separated by commas, spaces, or newlines (for example SCRUM-1, SCRUM-2).
  3. Click Run migration (copy only).

Each issue reports its own result — a per-issue list, never a single pass/fail flag:

SCRUM-1: copied

SCRUM-2: skipped (source field was empty)

SCRUM-3: failed — [error detail]

Panel wording, reproduced — not a screenshot.

The original field is never touched by this step. One issue’s failure never stops or rolls back the others.

Phase 2 — clear the original (irreversible, separately confirmed)

Only offered for issues phase 1 actually reported copied — never for a failed or skipped issue, since there would be nothing safely migrated to clear the original for. The screen states the stakes before you can proceed:

This step cannot be undone. This will permanently clear [source field]’s value on N issues. This cannot be undone — there is no backup and no way to restore the original value afterward. Only proceed once you have verified the copied values above are correct.

Panel wording, reproduced — not a screenshot.

The Clear original values button stays disabled until you type the exact phrase CLEAR ORIGINAL VALUES into the confirmation box — deliberately more friction than a checkbox, for a step with no rollback.

Running the migration wizard requires Jira administrator permission — checked server-side on every call, not just by which screen you happened to reach it from. A non-admin account is rejected with “You must be a Jira administrator to run this action.” and the attempt is logged.

11. JSM Requests & Safe JQL Search

A Secure Field added to a Jira Service Management request type appears on the portal request form for requesters and the portal view for agents, using the exact same allow-list, encryption, and audit behaviour as the issue-view surface. JSM request participants is one of the allow-list entry types (section 6) specifically for this surface.

Searching without leaking

Use Jira’s own IS EMPTY / IS NOT EMPTY JQL operators to find issues where the field has, or doesn’t have, a value set — for example cf[10146] IS NOT EMPTY. This works through Jira’s native structural check, needs no custom JQL function from this app, and can never expose what the value actually is — only whether one exists. CSV export and print view show only Not set or ••••••••, the same as the field’s own masked display.

12. The Secure Attachment Field

Contextra Secure Attachment is a second field type in the same app, sharing the identical allow-list, audit log, two-factor, and configuration screen as the text field — only the stored content differs: a small encrypted file instead of a short value.

Choose a file. Drop files to attach or browse. Up to 90 KB.

Panel wording, reproduced — not a screenshot.

  • Files are stored encrypted, out of Jira’s native Attachments panel entirely — not just hidden from it.
  • Reveal and download follow the exact same allow-list as the text field type.
  • 90 KB per file — a real, disclosed limit from how the encrypted envelope is stored (Forge’s key-value store), not an arbitrary choice. Larger files belong in Jira’s native attachments, or in File Field for Jira if they need upload rules instead of encryption.
  • Configuration — the allow-lists, 2FA, TTL and BYOK — is the exact same screen used for the text field type, reached the same way (section 4).

13. Limitations

These are published rather than buried, because finding them after paying is worse for everyone.

A value can only be set once the issue exists

Not available on the issue-create screen. This was checked directly against the platform’s own APIs: there is no hook that hands a not-yet-created issue’s id to the field before the create dialog closes, and the one API that could commit a value at that point would mean writing the plaintext straight into Jira’s own visible field — exactly what this app exists to prevent. Set the value from the issue view once the issue exists.

Two-factor code delivery is not yet wired to a provider

The gate itself is real, server-side, and enforced. What’s still pending is choosing and wiring an SMS, email, or authenticator-push vendor to actually deliver the code to the end user.

Webhook alerts are not yet enabled

Alerting logic for reveal and denied-reveal events exists in the app but the manifest does not yet declare the network permission a fully customer-supplied alert URL would need. The audit log remains the record of these events in the meantime.

Bring-your-own-key has no recovery path

A lost BYOK key permanently undecrypts every value encrypted under it. This is disclosed on the option itself, not just here.

Attachments are capped at 90 KB per file

A real constraint from the encrypted-value storage this field uses, not an arbitrary number. Larger files should stay in Jira’s native attachments, or use File Field for Jira if upload rules (not encryption) are what you need.

One permission is not granular

write:jira-work is required alongside the granular scopes because the legacy issue-update endpoint this app must use for its own field marker is not yet fully covered by a narrower scope — a platform gap, not a design choice.

14. Troubleshooting

What you seeWhyWhat to do
You don't have permission to view/edit this value. Your account is not on the field’s reveal/edit allow-list, or the allow-list is still empty (the default on a new field). Ask a Jira admin to add you, a group you belong to, or your project role, in the field’s configuration (section 6).
You don't have permission to view this audit log. Reveal access and audit-log access are separate allow-lists — being able to reveal the value doesn’t automatically grant audit visibility. Ask a Jira admin to add you to the field’s separate audit allow-list.
This value has expired. The field’s TTL passed since the value was saved — or, rarely, the value is genuinely gone for another reason. Either way it’s reported the same, clear way rather than a decryption error. Not an error. Save a new value if one is still needed.
This value could not be decrypted. A genuine integrity failure — distinct from an ordinary expiry. Contact support with the field name and roughly when the value was last saved.
An active licence is required for this action. The licence or evaluation is inactive. Renew or start an evaluation from the Marketplace listing. Stored values are unaffected.
You must be a Jira administrator to run this action. The migration wizard was invoked by a non-admin account. Run the migration as, or ask, a Jira administrator.
Clearing the original field requires explicit confirmation. Phase 2 of the migration wizard was invoked without the exact confirmation phrase typed. Type CLEAR ORIGINAL VALUES exactly into the confirmation box before clicking Clear.