Exchange format for audit software
GRCA-Planeth exports an audit concept as a JSON file in the format grcaplaneth-audit/1: the planned audit with its audit tasks, the requirements audited and the basis of their assessment. The auditor downloads the file in GRCA-Planeth and uploads it to the audit software. This guide describes the file format and the import rules precisely enough for audit software to read the file and update its records every time it is uploaded again.
The file
Each file contains exactly one audit concept as one JSON object.
| Property | Value |
|---|---|
| Origin | In GRCA-Planeth, in the audit concept via Export for audit software |
| File name | <key of the concept>.grcaplaneth-audit.json, e.g. AU-52.grcaplaneth-audit.json; without a key Audit-Concept-<ID>.grcaplaneth-audit.json. The name has no meaning for the import. |
| Encoding | UTF-8 without BOM; non-ASCII characters appear as they are, not as \u escapes |
| Formatting | indented with 2 spaces; no meaning for the import |
| Media type | application/json |
- Content by permission: The file contains only what the exporting person may see in GRCA-Planeth. Linked entries without read permission are missing without notice.
- Language: Titles and descriptions are in the language they are maintained in in GRCA-Planeth. For translated legal texts, such as EU law, the language the exporting person chose for legal texts in GRCA-Planeth applies.
- State: The file reflects the state at the time of export (
metadata.generated). Later changes reach the audit software only with the next export.
Structure
A document is a JSON object with exactly these nine fields; all are required.
| Field | Type | Content |
|---|---|---|
format |
string | always grcaplaneth-audit/1 |
uuid |
UUID | ID of the audit concept |
metadata |
object | title, time of export, generator, project |
audit_concept |
object | the audit concept |
audit_object |
object | the audited audit object, e.g. a process or an IT system |
scales |
object | the three rating scales risk, regulation, requirement |
subjects |
array | audited subjects: regulations, risks, standards |
requirements |
array | all requirements of the audit object, included or not |
audit |
object | the planned audit with its audit tasks tasks |

Cross-references within the document always use uuid; issue_id refers back to GRCA-Planeth. The description of the assessment procedure is embedded in the task, not kept in an array of its own.
Field reference
Required = the schema demands the field; "always" = GRCA-Planeth always writes it, but the schema allows it to be missing. No object contains fields other than those listed here.
Common types
UUID: string, lower case, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$.
Issue – an entry from GRCA-Planeth (concept, audit object, requirement, assessment procedure):
| Field | Type | Required | Meaning |
|---|---|---|---|
issue_id |
integer ≥ 1 | yes | ID in GRCA-Planeth |
issuekey |
string or null |
always | readable key, e.g. AU-12; null if none is assigned |
title |
string | yes | title |
description |
string | yes | plain text; one line per paragraph or list item, separated by \n; empty if there is no description |
description_html |
string | yes | the same description as cleaned HTML, as GRCA-Planeth stores it; empty if there is none |
Level – a level of a rating scale, as importance and rating name it:
| Field | Type | Required | Meaning |
|---|---|---|---|
code |
string, not empty | yes | ID of the level in its scale, e.g. 3 or H |
label |
string, not empty | yes | label, e.g. Hoch |
weight |
number | yes | weight; higher = more important; up to 2 decimal places |
metadata
| Field | Type | Required | Meaning |
|---|---|---|---|
title |
string, not empty | yes | title of the audit concept |
generated |
string, ISO 8601 with time zone | yes | time of export in UTC, e.g. 2026-10-25T14:03:11.482913+00:00 |
generator |
string | yes | always GRCA-Planeth |
project |
string | always | name of the project (source) the concept belongs to |
audit_concept and audit_object
Both are an Issue. audit_concept additionally has status (string or null, required), the processing status in GRCA-Planeth, e.g. Backlog.
scales
An object with exactly the keys risk, regulation and requirement. Each value is an array of at least one level, in the order the project defined:
| Field | Type | Required | Meaning |
|---|---|---|---|
code |
string, not empty | yes | ID of the level, unique within the scale |
label |
string, not empty | yes | label |
weight |
number | yes | weight |
description |
string | yes | explanation; may be empty |
color |
string #rrggbb, lower case |
yes | colour of the level in GRCA-Planeth |
subjects[]
Every regulation, risk and standard that at least one requirement addresses, exactly once. Subjects have no description.
| Field | Type | Required | Meaning |
|---|---|---|---|
uuid |
UUID | yes | ID in the exchange format |
type |
regulation, risk or standard |
yes | kind of subject |
issue_id |
integer | yes | ID in GRCA-Planeth |
issuekey |
string or null |
always | readable key |
title |
string | yes | title, e.g. Artikel 9 (4) |
rating |
level or null |
yes | rating in the audit object; always null for standards |
rating_inherited_from |
integer or null |
always | issue_id of the parent regulation whose rating a sub-regulation takes over; otherwise null |
requirements[]
All requirements of the audit object, sorted by title. Each is an Issue with these further fields (all required):
| Field | Type | Meaning |
|---|---|---|
uuid |
UUID | ID in the exchange format |
included |
boolean | true = is audited |
importance |
level or null |
applicable importance from the scale requirement; null = not rated |
proposed_importance |
level or null |
importance proposed by GRCA-Planeth |
deviates_from_proposal |
boolean | the auditor deviated from the proposal in importance or inclusion |
justification |
string | the auditor's justification; empty if there is none |
subjects |
array of UUID | the subjects the requirement addresses; may be empty |
assessment_procedures |
array of integer | issue_id of the chosen assessment procedures; possible for requirements not included as well |
audit
| Field | Type | Required | Meaning |
|---|---|---|---|
uuid |
UUID | yes | ID of the audit |
issue_id |
integer | no | issue "Audit" in GRCA-Planeth, once created there |
issuekey |
string or null |
no | its key, together with issue_id |
title |
string | yes | title of the audit (= title of the concept) |
tasks |
array | yes | audit tasks; may be empty |
audit.tasks[]
Sorted by importance.weight descending (null counts as weight 0), then by title.
| Field | Type | Required | Meaning |
|---|---|---|---|
uuid |
UUID | yes | ID of the audit task |
issue_id |
integer | no | issue "Audit Task" in GRCA-Planeth, once created there |
title |
string | yes | title (= title of the assessment procedure) |
assessment_procedure |
Issue | yes | the assessment procedure with its description, i.e. how to audit |
requirements |
array of UUID, at least 1 | yes | the included requirements this task assesses |
importance |
level or null |
yes | highest importance of its requirements |
Business rules
What is audited is in requirements[].included; how important it is, in importance. Both are already resolved: the audit software does not need to calculate anything.
Rating of the subjects
- A risk has a
ratingif it is linked to the audit object and rated there; otherwisenull. - A regulation has its own rating or, without one, that of its nearest rated parent regulation; then
rating_inherited_fromnames that parent'sissue_id. - A standard is not rated.
Proposal and decision
- GRCA-Planeth takes the highest rating (
weight) among the risks and regulations of a requirement. proposed_importanceis the level of the scalerequirementwith the highest weight this rating reaches; if it reaches none, the lightest level. Without a rating:null.- A requirement with a proposal is proposed for inclusion, one without is not.
- The auditor can change the level and the inclusion.
importanceandincludedcontain what applies. Every deviation setsdeviates_from_proposaland is justified injustification.
How tasks arise
- For each assessment procedure chosen for at least one included requirement there is exactly one task.
- If a procedure assesses several requirements, its task names all of them in
requirements. - Requirements that are not included create no task, even if procedures are chosen for them.
- The
importanceof a task is the highestimportanceof its requirements. - An included requirement without a chosen procedure appears in no task; the audit software can show it as an open point.
Import rules
An audit concept is changed over weeks and exported several times. Match every record by its uuid, never by title or position.
Stable IDs
| Record | uuid derived from |
stays the same as long as |
|---|---|---|
Audit concept (top-level uuid) |
random value, stored in GRCA-Planeth | the concept exists |
Audit (audit.uuid) |
UUIDv5(concept UUID, audit) |
the concept exists |
| Task | UUIDv5(concept UUID, task:<issue_id of the procedure>) |
the same procedure is chosen |
| Requirement | UUIDv5(concept UUID, requirement:<issue_id>) |
it belongs to the audit object |
| Subject | UUIDv5(concept UUID, subject:<issue_id>) |
a requirement addresses it |
UUIDs are unique across concepts: the same requirement has two different uuid in two concepts. The copy of an audit object in GRCA-Planeth gets a new concept with new UUIDs. The derivation is only an explanation; use the values supplied.
Matching on a repeated import
- Find the concept by the top-level
uuid; unknown = create a new concept. - Update or create the audit, tasks, requirements and subjects by their
uuid. - Mark records missing from the new export as obsolete, do not delete them: an audit task may already have been worked on. GRCA-Planeth does the same with its own audit tasks.
- A task becomes obsolete when its procedure is deselected or all its requirements are excluded; a requirement, when it is removed from the audit object.
Detecting changes
With an unchanged state, two exports produce the same file in content. They differ only in metadata.generated, and the order of keys in JSON objects (for example in scales) is not fixed. The order of arrays, by contrast, is stable. The file carries no version counter: to detect whether an uploaded file changes anything, compute a hash over the document with sorted keys and without metadata.generated.
Format version
- Check that
formatis exactlygrcaplaneth-audit/1and reject files with any other value. - Within version 1, only optional fields are added; ignore unknown fields. If you validate strictly against a locally stored copy of the schema, update it with every new version of this guide.
- Removed, renamed or redefined fields lead to
grcaplaneth-audit/2.
Complete example
The following document was produced by the export function of GRCA-Planeth and validated against the schema. It contains:
- an included requirement with two tasks,
- an excluded requirement with a justification,
- a regulation that inherits its rating,
- an audit that already exists as an issue in GRCA-Planeth. Only the second task has been created there; the first was added later and therefore has no
issue_idyet.
{
"format": "grcaplaneth-audit/1",
"uuid": "3f2b8c4e-9d1a-4b6e-8f7c-2a5d9e0b1c34",
"metadata": {
"title": "Prüfungskonzept IAM 2026",
"generated": "2026-10-25T14:03:11+00:00",
"generator": "GRCA-Planeth",
"project": "Interne Revision"
},
"audit_concept": {
"issue_id": 196002,
"issuekey": "AU-52",
"title": "Prüfungskonzept IAM 2026",
"description": "Prüfung des Identity & Access Managements im Geschäftsjahr 2026.",
"description_html": "<p>Prüfung des Identity & Access Managements im Geschäftsjahr 2026.</p>",
"status": "Backlog"
},
"audit_object": {
"issue_id": 3660,
"issuekey": "AU-1",
"title": "Identity & Access Management",
"description": "Prozesse und Verfahren zur Identifizierung, Authentifizierung und Autorisierung.",
"description_html": "<p>Prozesse und Verfahren zur Identifizierung, Authentifizierung und Autorisierung.</p>"
},
"scales": {
"risk": [
{ "code": "1", "label": "Gering", "weight": 1.0, "description": "", "color": "#5aa469" },
{ "code": "2", "label": "Mittel", "weight": 2.0, "description": "", "color": "#e3b505" },
{ "code": "3", "label": "Hoch", "weight": 3.0, "description": "", "color": "#e8833a" },
{ "code": "4", "label": "Sehr hoch", "weight": 4.0, "description": "", "color": "#c8423b" }
],
"regulation": [
{ "code": "1", "label": "Niedrig", "weight": 1.0, "description": "", "color": "#9dbbe0" },
{ "code": "2", "label": "Mittel", "weight": 2.0, "description": "", "color": "#4f86c6" },
{ "code": "3", "label": "Hoch", "weight": 3.0, "description": "", "color": "#1f4e8c" }
],
"requirement": [
{ "code": "1", "label": "Gering", "weight": 1.0, "description": "Kann im Prüfungskonzept entfallen.", "color": "#8fbf9f" },
{ "code": "2", "label": "Mittel", "weight": 2.0, "description": "Stichprobenartig prüfen.", "color": "#d9b44a" },
{ "code": "3", "label": "Hoch", "weight": 3.0, "description": "Im Prüfungskonzept vorsehen.", "color": "#d9773a" },
{ "code": "4", "label": "Sehr hoch", "weight": 4.0, "description": "Vorrangig und vollständig prüfen.", "color": "#b8322d" }
]
},
"subjects": [
{
"uuid": "b6d3a015-b15b-55e4-a286-b5b01cb45a6a",
"type": "regulation",
"issue_id": 30411,
"issuekey": null,
"title": "Artikel 9 (4)",
"rating": { "code": "3", "label": "Hoch", "weight": 3.0 },
"rating_inherited_from": 30402
},
{
"uuid": "418585cb-5865-511e-8a35-41a4d9e55ed8",
"type": "risk",
"issue_id": 5402,
"issuekey": "AU-31",
"title": "Unberechtigte Zugriffe durch verwaiste Konten",
"rating": { "code": "3", "label": "Hoch", "weight": 3.0 },
"rating_inherited_from": null
},
{
"uuid": "f21ca482-7b5a-56b3-9ada-788afa08a43a",
"type": "standard",
"issue_id": 81233,
"issuekey": null,
"title": "ISO/IEC 27001 A.5.18 Zugangsrechte",
"rating": null,
"rating_inherited_from": null
}
],
"requirements": [
{
"uuid": "5da9c3ff-51c0-52cd-889e-f6386ea4affe",
"issue_id": 5488,
"issuekey": "AU-10",
"title": "IAM – Rezertifizierung der Zugriffsrechte",
"description": "jährliche Rezertifizierung\nEntzug nicht bestätigter Rechte",
"description_html": "<ul><li>jährliche Rezertifizierung</li><li>Entzug nicht bestätigter Rechte</li></ul>",
"included": true,
"importance": { "code": "3", "label": "Hoch", "weight": 3.0 },
"proposed_importance": { "code": "3", "label": "Hoch", "weight": 3.0 },
"deviates_from_proposal": false,
"justification": "",
"subjects": [
"b6d3a015-b15b-55e4-a286-b5b01cb45a6a",
"418585cb-5865-511e-8a35-41a4d9e55ed8",
"f21ca482-7b5a-56b3-9ada-788afa08a43a"
],
"assessment_procedures": [5500, 5501]
},
{
"uuid": "43da23e2-e523-52c7-a76a-32dd6d8fbaf6",
"issue_id": 5489,
"issuekey": "AU-11",
"title": "IAM – Aufbewahrung von Berechtigungsnachweisen",
"description": "",
"description_html": "",
"included": false,
"importance": { "code": "3", "label": "Hoch", "weight": 3.0 },
"proposed_importance": { "code": "3", "label": "Hoch", "weight": 3.0 },
"deviates_from_proposal": true,
"justification": "Im Vorjahr ohne Feststellungen geprüft.",
"subjects": ["b6d3a015-b15b-55e4-a286-b5b01cb45a6a"],
"assessment_procedures": []
}
],
"audit": {
"uuid": "3982c91b-4164-55fb-aab8-bf5f79ce4891",
"issue_id": 196014,
"issuekey": "AU-60",
"title": "Prüfungskonzept IAM 2026",
"tasks": [
{
"uuid": "7eb40882-ae06-528a-9f8b-6a510ee58dff",
"title": "Berechtigungen regelmäßig rezertifizieren",
"assessment_procedure": {
"issue_id": 5500,
"issuekey": "AU-39",
"title": "Berechtigungen regelmäßig rezertifizieren",
"description": "Zugriffsrechte werden mindestens jährlich durch die Fachverantwortlichen bestätigt.",
"description_html": "<p>Zugriffsrechte werden mindestens jährlich durch die Fachverantwortlichen bestätigt.</p>"
},
"requirements": ["5da9c3ff-51c0-52cd-889e-f6386ea4affe"],
"importance": { "code": "3", "label": "Hoch", "weight": 3.0 }
},
{
"uuid": "c90da492-2c8a-5516-8b4c-ab7e8bea6fa1",
"issue_id": 196015,
"title": "Stichprobe privilegierter Konten",
"assessment_procedure": {
"issue_id": 5501,
"issuekey": "AU-40",
"title": "Stichprobe privilegierter Konten",
"description": "25 privilegierte Konten gegen die Genehmigungen abgleichen.",
"description_html": "<p>25 privilegierte Konten gegen die Genehmigungen abgleichen.</p>"
},
"requirements": ["5da9c3ff-51c0-52cd-889e-f6386ea4affe"],
"importance": { "code": "3", "label": "Hoch", "weight": 3.0 }
}
]
}
}
Validation and checklist
The schema in the appendix is JSON Schema Draft 2020-12; any validator for this version checks a file completely. Save it as grcaplaneth-audit-1.schema.json. Its $id is only an identifier, not an address to fetch. Example in Python:
import json
import jsonschema
with open("grcaplaneth-audit-1.schema.json", encoding="utf-8") as file:
schema = json.load(file)
with open("AU-52.grcaplaneth-audit.json", encoding="utf-8") as file:
document = json.load(file)
if document.get("format") != "grcaplaneth-audit/1":
raise ValueError("Not an audit concept in the format grcaplaneth-audit/1")
jsonschema.Draft202012Validator(schema).validate(document)
Before the first productive import:
- Uploaded file read as UTF-8
formatchecked and file validated against the schema- All records matched by
uuid, not by title orissue_id - Uploading the same or a newer file again updates instead of duplicating
- Missing records marked as obsolete instead of deleted
- Unknown fields are ignored
importance: nullandrating: nullare displayed without errors- Included requirements without a task are shown as open points
Questions about the format are answered by the operator of the GRCA-Planeth instance the file comes from.
Appendix: JSON schema
The binding schema for grcaplaneth-audit/1, as of 2026-10-25. Save it as grcaplaneth-audit-1.schema.json.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://grca.planeth.de/schema/grcaplaneth-audit-1.schema.json",
"title": "GRCA-Planeth audit concept, format 1",
"description": "An Audit Concept with the audit it plans, for audit management software. Modelled on the OSCAL Assessment Plan: subjects (what is assessed), requirements (the reviewed controls) and tasks (one per assessment procedure). Every uuid stays the same when the concept is exported again, so an import can update instead of duplicate.",
"type": "object",
"required": ["format", "uuid", "metadata", "audit_concept", "audit_object", "scales", "subjects", "requirements", "audit"],
"additionalProperties": false,
"properties": {
"format": { "const": "grcaplaneth-audit/1" },
"uuid": {
"description": "The Audit Concept's stable ID.",
"$ref": "#/$defs/uuid"
},
"metadata": {
"type": "object",
"required": ["title", "generated", "generator"],
"additionalProperties": false,
"properties": {
"title": { "$ref": "#/$defs/text" },
"generated": {
"description": "When the document was written (ISO 8601 with time zone).",
"type": "string",
"format": "date-time"
},
"generator": { "const": "GRCA-Planeth" },
"project": {
"description": "The project (source) the concept belongs to.",
"type": "string"
}
}
},
"audit_concept": {
"allOf": [{ "$ref": "#/$defs/issue" }],
"properties": {
"status": { "type": ["string", "null"] }
},
"unevaluatedProperties": false
},
"audit_object": {
"description": "What is audited, e.g. a process or an IT system.",
"allOf": [{ "$ref": "#/$defs/issue" }],
"unevaluatedProperties": false
},
"scales": {
"description": "The rating scales used: risk and regulation for the subjects, requirement for the importance of requirements and tasks.",
"type": "object",
"required": ["risk", "regulation", "requirement"],
"additionalProperties": false,
"properties": {
"risk": { "$ref": "#/$defs/scale" },
"regulation": { "$ref": "#/$defs/scale" },
"requirement": { "$ref": "#/$defs/scale" }
}
},
"subjects": {
"description": "The regulations, risks and standards the requirements address.",
"type": "array",
"items": {
"type": "object",
"required": ["uuid", "type", "issue_id", "title", "rating"],
"additionalProperties": false,
"properties": {
"uuid": { "$ref": "#/$defs/uuid" },
"type": { "enum": ["regulation", "risk", "standard"] },
"issue_id": { "$ref": "#/$defs/issue_id" },
"issuekey": { "$ref": "#/$defs/issuekey" },
"title": { "type": "string" },
"rating": {
"description": "The rating in the Audit Object; standards are not rated.",
"oneOf": [{ "$ref": "#/$defs/level" }, { "type": "null" }]
},
"rating_inherited_from": {
"description": "issue_id of the parent regulation whose rating a sub-regulation has.",
"oneOf": [{ "$ref": "#/$defs/issue_id" }, { "type": "null" }]
}
}
}
},
"requirements": {
"description": "Every requirement of the Audit Object, included in the audit or not.",
"type": "array",
"items": {
"allOf": [{ "$ref": "#/$defs/issue" }],
"required": ["uuid", "included", "importance", "proposed_importance", "deviates_from_proposal", "justification", "subjects", "assessment_procedures"],
"properties": {
"uuid": { "$ref": "#/$defs/uuid" },
"included": {
"description": "Whether the requirement is audited.",
"type": "boolean"
},
"importance": {
"description": "The level that applies: the auditor's, else the proposal.",
"oneOf": [{ "$ref": "#/$defs/level" }, { "type": "null" }]
},
"proposed_importance": {
"description": "Derived from the heaviest rating of the requirement's risks and regulations.",
"oneOf": [{ "$ref": "#/$defs/level" }, { "type": "null" }]
},
"deviates_from_proposal": { "type": "boolean" },
"justification": {
"description": "Why the auditor deviated from the proposal (or a remark).",
"type": "string"
},
"subjects": {
"description": "uuids of the subjects the requirement addresses.",
"type": "array",
"items": { "$ref": "#/$defs/uuid" }
},
"assessment_procedures": {
"description": "issue_ids of the chosen assessment procedures.",
"type": "array",
"items": { "$ref": "#/$defs/issue_id" }
}
},
"unevaluatedProperties": false
}
},
"audit": {
"description": "The audit planned by the concept.",
"type": "object",
"required": ["uuid", "title", "tasks"],
"additionalProperties": false,
"properties": {
"uuid": { "$ref": "#/$defs/uuid" },
"issue_id": {
"description": "The Audit issue in GRCA-Planeth, once created from the concept.",
"$ref": "#/$defs/issue_id"
},
"issuekey": { "$ref": "#/$defs/issuekey" },
"title": { "type": "string" },
"tasks": {
"description": "One Audit Task per assessment procedure chosen for an included requirement, the most important first.",
"type": "array",
"items": {
"type": "object",
"required": ["uuid", "title", "assessment_procedure", "requirements", "importance"],
"additionalProperties": false,
"properties": {
"uuid": { "$ref": "#/$defs/uuid" },
"issue_id": {
"description": "The Audit Task issue in GRCA-Planeth, once created from the concept.",
"$ref": "#/$defs/issue_id"
},
"title": { "type": "string" },
"assessment_procedure": {
"allOf": [{ "$ref": "#/$defs/issue" }],
"unevaluatedProperties": false
},
"requirements": {
"description": "uuids of the included requirements the task assesses.",
"type": "array",
"minItems": 1,
"items": { "$ref": "#/$defs/uuid" }
},
"importance": {
"description": "The highest importance of its requirements.",
"oneOf": [{ "$ref": "#/$defs/level" }, { "type": "null" }]
}
}
}
}
}
}
},
"$defs": {
"text": { "type": "string", "minLength": 1 },
"uuid": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"issue_id": {
"description": "The issue's id in GRCA-Planeth.",
"type": "integer",
"minimum": 1
},
"issuekey": { "type": ["string", "null"] },
"issue": {
"type": "object",
"required": ["issue_id", "title", "description", "description_html"],
"properties": {
"issue_id": { "$ref": "#/$defs/issue_id" },
"issuekey": { "$ref": "#/$defs/issuekey" },
"title": { "type": "string" },
"description": {
"description": "Plain text, one line per paragraph or list item.",
"type": "string"
},
"description_html": { "type": "string" }
}
},
"level": {
"type": "object",
"required": ["code", "label", "weight"],
"additionalProperties": false,
"properties": {
"code": { "$ref": "#/$defs/text" },
"label": { "$ref": "#/$defs/text" },
"weight": { "type": "number" }
}
},
"scale": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["code", "label", "weight", "description", "color"],
"additionalProperties": false,
"properties": {
"code": { "$ref": "#/$defs/text" },
"label": { "$ref": "#/$defs/text" },
"weight": { "type": "number" },
"description": { "type": "string" },
"color": { "type": "string", "pattern": "^#[0-9a-f]{6}$" }
}
}
}
}
}