Skip to main content
ISOwl uses a single Zustand store with the persist middleware to manage all application state. The store is exported from src/store/useSGSIStore.js and is the single source of truth for authentication, tenant data, compliance metrics, assets, risks, controls, audits, evidence, and findings.
import { useSGSIStore } from './store/useSGSIStore';

State shape

Authentication and session

FieldTypeDescription
isAuthenticatedbooleanWhether the current user is logged in
authUserobjectAuthenticated user record — see shape below
currentUserRole'CISO' | 'AUDITOR' | 'OWNER'Active role for the current session
authUser shape:
FieldTypeDescription
namestringDisplay name
emailstringLogin email
rolestringAssigned role
type'AGENCY' | 'CLIENT'Account type — agencies can manage multiple tenants
tenantIdstring?Tenant identifier (CLIENT accounts only)

Multi-tenant

FieldTypeDescription
currentTenantstringID of the currently active tenant
tenantsArray<{ id: string, name: string }>All tenants accessible to the current user
tenantDataobjectPer-tenant data keyed by tenantId — see structure below
tenantData[tenantId] shape:
KeyTypeDescription
clausesClause[]Clause list for the tenant
controlsControl[]Annex A controls for the tenant
clauseStatesobjectRequirement state map keyed by requirement ID
assetsAsset[]Asset inventory
risksRisk[]Risk register
auditsAudit[]Audit records
evidencesEvidence[]Evidence items
findingsFinding[]PAC findings

Active workspace data

The following fields reflect the currently active tenant. They are updated automatically when you call switchTenant.

Clauses

FieldTypeDescription
clausesArray<{ id: string, name: string, progress: number }>ISO 27001 clause list
clauseStates{ [reqId]: ClauseState }Requirement state map
ClauseState shape:
FieldTypeDescription
statusstringConformance status
maturitynumberMaturity level 0–5
ownerstringResponsible person or team
lastReviewDatestringISO date of last review
notesstringFree-text notes

Controls

FieldTypeDescription
controlsControl[]ISO 27002:2022 Annex A control list
Control shape:
FieldTypeDescription
idstringControl identifier (e.g. A.5.1)
domainstringControl domain (e.g. Organizacionales)
namestringControl name
descriptionstringControl description
statusstringEvaluation status — defaults to 'No Evaluado'
responsiblestringResponsible person or team
lastReviewstringISO date of last review

Assets

FieldTypeDescription
assetsAsset[]Asset inventory for the active tenant
Asset shape:
FieldTypeDescription
idstringAsset identifier
namestringAsset name
typestringAsset type (e.g. Información, Hardware, Software, Infraestructura)
ownerstringAsset owner
cnumberConfidentiality score 1–3
inumberIntegrity score 1–3
dnumberAvailability score 1–3

Risks

FieldTypeDescription
risksRisk[]Risk register for the active tenant
Risk shape:
FieldTypeDescription
idstringAuto-generated identifier (e.g. R001)
assetIdstringLinked asset ID
pillarsstring[]Compromised CIA pillars (e.g. ['C', 'I'])
probabilitynumberInherent probability 1–5
impactnumberInherent impact 1–5
treatmentOptionstring'Mitigar' | 'Aceptar' | 'Transferir' | 'Evitar'
treatmentJustificationstringManagement justification (non-Mitigar treatments)
controlsArray<{ id: string, efficacy: number }> | nullApplied Annex A controls with efficacy %
residualRisknumberResidual risk score after applying controls (1–25)
datestringISO date the risk was registered

Audits

FieldTypeDescription
auditsAudit[]Audit records for the active tenant
Audit shape (key fields):
FieldTypeDescription
idstringAudit identifier
typestringAudit type
fechastringISO date of the audit
statusstringAudit status

Evidence

FieldTypeDescription
evidencesEvidence[]Evidence items for the active tenant
Evidence shape:
FieldTypeDescription
idstringEvidence identifier
namestringEvidence name
categorystringCategory
descriptionstringDescription
relatedTostringControl or requirement reference
fileNamestringUploaded file name
versionstringEvidence version
uploadedAtstringISO date of upload

Findings

FieldTypeDescription
findingsFinding[]PAC findings for the active tenant
Finding shape:
FieldTypeDescription
idstringFinding identifier
typestringFinding type (e.g. Major NC, Minor NC, Observation)
requirementIdstringRelated ISO 27001 requirement ID
descriptionstringDescription of the finding
pacstringCorrective action plan
responsiblestringPerson responsible for closure
dueDatestringTarget closure date
progressnumberCompletion percentage 0–100
closingEvidencestringEvidence reference for closure
statusstring'Abierto' | 'En Tratamiento' | 'Cerrado'
createdAtstringISO date the finding was created

Authentication methods

login(email, password)

Attempts to authenticate the user with the provided credentials.
ParameterTypeDescription
emailstringUser email address
passwordstringUser password
Returns: booleantrue if authentication succeeded, false otherwise.
const success = useSGSIStore.getState().login('user@example.com', 'password');

logout()

Clears the authenticated session and resets auth state. Returns: void

Multi-tenant methods

switchTenant(newTenantId)

Switches the active workspace to the specified tenant. Loads that tenant’s data into the top-level active workspace fields (clauses, controls, assets, risks, etc.).
ParameterTypeDescription
newTenantIdstringThe ID of the tenant to activate
Returns: void

addTenant(name)

Creates a new tenant with an auto-generated ID and appends it to the tenants list.
ParameterTypeDescription
namestringDisplay name for the new tenant
Returns: { id: string, name: string } — the newly created tenant object.

setRole(role)

Updates the active user role for the current session.
ParameterTypeDescription
role'CISO' | 'AUDITOR' | 'OWNER'The role to activate
Returns: void

Compliance metrics methods

All metrics methods read from the active tenant’s data. Call them on a component level using the useSGSIStore hook or directly via useSGSIStore.getState().

getGlobalCompliance()

Returns the overall compliance percentage across all ISO 27001 Clauses 4–10 requirements. Returns: number — value between 0 and 100.

getMaturityScore()

Returns the overall Annex A maturity score based on implemented controls. Returns: number — value between 0 and 100.

getClauseProgress(clauseId)

Returns the compliance percentage for a specific top-level clause.
ParameterTypeDescription
clauseIdstringClause identifier (e.g. '4', '5')
Returns: number — value between 0 and 100.

getSubclauseProgress(subclauseId)

Returns the compliance percentage for a specific subclause.
ParameterTypeDescription
subclauseIdstringSubclause identifier (e.g. '4.1', '6.1')
Returns: number — value between 0 and 100.

getClauseMaturity(clauseId)

Returns the average maturity score for all requirements within a clause.
ParameterTypeDescription
clauseIdstringClause identifier
Returns: number — float between 0 and 5.

getDomainProgress()

Returns progress data for all four Annex A control domains. Returns: Array<{ domain: string, score: number, total: number }>
// Example output
[
  { domain: 'Organizacionales', score: 24, total: 37 },
  { domain: 'Personas',         score: 6,  total: 8  },
  { domain: 'Físicos',          score: 10, total: 14 },
  { domain: 'Tecnológicos',     score: 20, total: 34 },
]

getOpenMajorNCs()

Counts the number of open major nonconformity findings. Returns: number

Requirement state methods

updateRequirementState(reqId, state)

Persists the conformance state for a single requirement.
ParameterTypeDescription
reqIdstringRequirement identifier (e.g. '4.1.1')
stateobjectPartial or full state — see fields below
state fields:
FieldTypeDescription
statusstringConformance status
maturitynumberMaturity level 0–5
ownerstringResponsible person or team
lastReviewDatestringISO date
notesstringFree-text notes
Returns: void

getRequirementState(reqId)

Retrieves the current state for a single requirement.
ParameterTypeDescription
reqIdstringRequirement identifier
Returns: { status, maturity, owner, lastReviewDate, notes }

Asset methods

addAsset(asset)

Adds a new asset to the inventory.
ParameterTypeDescription
assetAssetAsset object — see Asset shape above
Returns: void

updateAsset(id, updatedData)

Merges updatedData into the existing asset record.
ParameterTypeDescription
idstringAsset identifier
updatedDataPartial<Asset>Fields to update
Returns: void

deleteAsset(id)

Removes the asset and all risks linked to it.
ParameterTypeDescription
idstringAsset identifier
Returns: void
Deleting an asset permanently removes all risks that reference it. This action cannot be undone.

getAssetCriticality(c, i, d)

Calculates the criticality score for an asset given its CIA scores.
ParameterTypeDescription
cnumberConfidentiality score 1–3
inumberIntegrity score 1–3
dnumberAvailability score 1–3
Returns: numbermax(c, i, d)

getCategoryColor(criticality)

Returns the Tailwind CSS color class for a given criticality score.
ParameterTypeDescription
criticalitynumberCriticality score 1–5
Returns: string — Tailwind background utility class (e.g. 'bg-rose-500' for criticality 3, 'bg-amber-500' for 2, 'bg-emerald-500' for 1).

Risk methods

addRisk(riskData)

Appends a new risk to the register.
ParameterTypeDescription
riskDataRiskRisk object — see Risk shape above
Returns: void

Annex A control methods

updateControlStatus(id, newStatus)

Updates the evaluation status of an Annex A control.
ParameterTypeDescription
idstringControl identifier (e.g. 'A.5.1')
newStatusstringNew status value
Returns: void

Audit and finding methods

addAuditFinding(finding)

Adds a finding record linked to an audit.
ParameterTypeDescription
findingobjectFinding data object
Returns: void

addFinding(finding)

Adds a new PAC finding to the findings list.
ParameterTypeDescription
findingFindingFinding object — see Finding shape above
Returns: void

updateFinding(id, data)

Merges data into an existing PAC finding.
ParameterTypeDescription
idstringFinding identifier
dataPartial<Finding>Fields to update
Returns: void

closeFinding(id)

Marks a PAC finding as closed.
ParameterTypeDescription
idstringFinding identifier
Returns: void

Evidence methods

addEvidence(evidence)

Adds a new evidence item to the register.
ParameterTypeDescription
evidenceEvidenceEvidence object — see Evidence shape above
Returns: void

deleteEvidence(id)

Removes an evidence item permanently.
ParameterTypeDescription
idstringEvidence identifier
Returns: void

Persistence

The store uses the Zustand persist middleware backed by localStorage.
SettingValue
Storage key'sgsi-storage'
Storage backendlocalStorage
Middlewarezustand/middleware/persist
All state — including tenant data, requirement states, assets, risks, controls, evidence, and findings — is automatically serialized to localStorage on every state change and rehydrated on page load.
localStorage is browser-scoped and not shared between devices or users. Use the PDF export or SoA export features to create portable backups of your ISMS data.
The localStorage cap is typically 5–10 MB depending on the browser. For most ISMS implementations this limit is not a concern, but organisations with very large evidence or finding lists should monitor storage usage.

Build docs developers (and LLMs) love