0Purpose and limits#
This document describes how we build software. It exists so that you can judge our engineering practice before you hire us, rather than after.
This is a self-assessment
It is a self-assessment. We are not certified against any standard described here, and no third party has audited these claims. Where we align with a public framework, we say so and say how far. Where we do not, we say that too. If your organisation requires audited assurance, you should commission it independently.
We publish this because it is checkable. Most of what follows produces artifacts you can inspect, and we would rather be held to a written standard than describe ourselves in adjectives.
1How we work#
We build complete systems. A typical project runs from a few weeks to a few months, and we take responsibility for the whole thing, the application, the data pipelines, the integrations, and the infrastructure it runs on.
Every project runs in up to three steps. Assess, in which we agree what is being built and what it will touch. Build, in which the architecture and threat model are written, the system is developed against the practices in this document, and you receive it with everything described in Section 9 at handover. Run, if you want us to, in which we keep it running and improving (Section 10); otherwise your own team takes over.
Decisions of consequence are written down as they are made, with the reasoning attached. You receive that record at handover, so the system arrives with its history rather than as an artifact nobody can explain.
We work in the open with you throughout. There is no phase in which the system is a black box.
2Before we build#
Security work starts at the Assess step, not at review.
Before development begins we establish what data the system will handle, where that data comes from and goes, who and what will be able to reach it, and which actions the system will be able to take in the world. For AI systems we additionally establish what the model is permitted to do, what it will be given access to, and what happens when it behaves incorrectly, not if, but when.
This produces a written threat model that identifies the realistic failure modes and the control for each. It is a working document, revised as the system changes, and it is delivered to you at the end.
Where a requirement cannot be met safely, we say so during the Assess step. We would rather lose the work than build something we would not run ourselves.
Aligned withNIST SSDF (Prepare the Organization), NIST SP 800-218A.
3Handling your data and access#
We treat your environment and your data as things we are borrowing. This section describes exactly how.
Where we build. We work either way. If you have an existing cloud environment, we build inside it using accounts you provision, scoped to what the work requires and nothing more. If you are starting from scratch, we build in a dedicated environment on our side and hand the whole thing over, infrastructure as code, accounts, and documentation, so that what you receive is yours outright, with no dependency on us to run it.
Access. Access is granted per project, per person, at the minimum level the work requires. We do not share accounts between team members or between clients. Where you provision our access, you retain the ability to see and revoke it at any time without going through us.
Secrets and credentials. Credentials live in a managed secret store, Google Secret Manager or the equivalent in your environment. They are never committed to source control, never placed in prompts or model context, never sent over chat or email, and never held in local files. Automated secret scanning runs against our repositories.
Your data. We use the minimum data required to do the work. Where an AI system must be built and evaluated against real data, which is usually unavoidable, because a system tested only on synthetic data has not really been tested, we agree the scope with you in advance, minimise what is used, and prefer redacted or masked datasets where the use case allows. Personally identifiable information is stripped or masked wherever it is not essential to the behaviour being built.
Your data is never used to train third-party models. Where we use AI tooling in development, we use configurations that exclude your data from provider training.
When we finish. Our access is revoked at handover. If you would prefer we keep access, for the Run step or for future work, that is your decision to make explicitly, in writing, rather than something that happens by default. Working copies of your data are deleted at project close.
Logging. System logs are configured to exclude sensitive content. Where model inputs and outputs are logged for debugging or evaluation, sensitive fields are redacted before they are written.
4How we write code#
All work is version controlled. Nothing reaches a main branch without review by a second engineer. This holds on every project regardless of size, including work that only one of us is building.
Dependencies are pinned to explicit versions and scanned for known vulnerabilities on every build. New dependencies are added deliberately, not casually; a package that is unmaintained, thinly used, or does more than the job requires is a liability we would rather not inherit.
Static analysis and secret scanning run automatically on every change. Findings block the merge rather than generating a report nobody reads.
Code is written to be handed over. That means it is documented at the level a competent engineer who has never seen it would need, because at the end of the project that is exactly who will be reading it.
Aligned withNIST SSDF (Produce Well-Secured Software).
5How code reaches production#
Builds are automated. Nothing is deployed from an engineer's machine.
Every artifact we ship carries signed build provenance, a cryptographic record of what source it was built from, by which pipeline, and when. You can verify it yourself with standard tooling, without asking us anything. Every release ships with a software bill of materials listing every dependency it contains.
Our pipelines meet SLSA Build Level 3. That means the build platform is hardened, builds are isolated from one another, and signing material is not reachable from any build step the code itself can influence, provenance is generated by an isolated workflow the calling build cannot alter, with keyless signing. The provenance we ship can be verified against that standard using standard tooling; you do not need to trust the claim.
Development, staging and production environments are separated, with separate credentials. Deployment to production is gated: an artifact that fails a security check does not ship.
Aligned withSLSA v1.1 Build Track, NIST SSDF (Protect the Software).
6Building AI systems safely#
AI systems fail in ways conventional software does not. This section describes what we do about each of the failure modes catalogued in the OWASP Top 10 for LLM Applications, and, for systems involving agents, the OWASP Top 10 for Agentic Applications.
Prompt injection. Instructions and untrusted content are kept structurally separate. Content retrieved from documents, web pages, email or any other external source is treated as data, never as instruction. Tool calls proposed by a model are validated against an explicit schema and permission set before execution.
Sensitive information disclosure. Secrets never enter prompts or model context. Inputs and outputs are filtered for sensitive content. Logs are scrubbed before they are written.
Supply chain. Models are obtained from verified sources. Serialised model files from untrusted origins are never loaded, because loading one is equivalent to executing arbitrary code. Every release carries a dependency inventory covering model components as well as software packages.
Data and model poisoning. Where a project involves fine-tuning or client-controlled training data, provenance and integrity of that data are established before use, and model behaviour is evaluated before and after. Where a system is built on hosted model APIs without fine-tuning, this risk sits with the model provider and is outside our control; we say which case applies to your system rather than implying coverage we do not have.
Improper output handling. Model output is treated as untrusted input everywhere downstream. It is never passed directly into code execution, database queries, shell commands, or rendered markup without validation and escaping appropriate to the destination.
Excessive agency. Agents are given the narrowest capability that accomplishes the task. Each agent has its own identity and credentials rather than sharing a privileged account. Tool access is explicitly enumerated rather than inherited. Actions that are irreversible, costly, or externally visible, deleting records, sending messages, moving money, are gated behind human confirmation unless you decide otherwise, deliberately and in writing.
System prompt leakage. Nothing secret lives in a system prompt. No security property of a system we build depends on its prompt remaining hidden, because prompts leak.
Vector and embedding weaknesses. In retrieval systems, access control is enforced at retrieval time, so that a query can only reach documents the requesting user is entitled to see. Where a system serves multiple tenants, their data is isolated in the vector store. Ingestion sources are controlled, because anything that can write to the index can influence every answer the system gives.
Misinformation. Answers are grounded in retrieved sources rather than model recall wherever the use case allows, with citation back to source where feasible. Systems are evaluated against a task-specific test set before release, and the evaluation is delivered to you.
Unbounded consumption. Rate limits, token ceilings, loop bounds and spend alerts are configured before a system reaches production. An AI system without consumption limits is a financial liability as much as a technical one.
For agent systems, additionally: persisted agent memory is treated as untrusted on read, because state that survives between sessions can be poisoned in one and used in the next. In multi-agent systems, output from one agent is validated before another acts on it rather than being trusted by virtue of its origin.
Aligned withOWASP Top 10 for LLM Applications (2026), OWASP Top 10 for Agentic Applications (2026), NIST SP 800-218A.
7Cloud foundations#
Identity and access are configured on least privilege as a matter of course. Permissions are granted for what a person or workload actually needs rather than assigned as broad predefined roles for convenience. Where a project requires it, human and machine identities are separated so that applications run under their own service accounts rather than borrowing a person's.
We do not use long-lived credentials. Access is granted through short-lived, automatically expiring tokens via workload identity federation rather than downloaded key files, so there is no permanent credential to leak, rotate or forget.
All cloud infrastructure is defined in Terraform and version controlled. Environments are reproducible from source; nothing significant exists only because someone configured it by hand in a console.
Data is encrypted in transit and at rest. Where you want control of your own keys, we configure customer-managed encryption, which means you can revoke access to your own data independently of us.
Services communicate over private networking. Public internet exposure exists only where a system genuinely requires it, and is deliberate rather than default.
Logging, monitoring and alerting are configured as part of the build, before a system goes live, not added after the first incident. Cloud audit logs are retained and protected against modification by the identities they record.
Aligned withGoogle Cloud Architecture Framework (security), CIS benchmarks.
8Testing and verification#
Systems are tested at three levels: conventional testing of code correctness, security testing against the controls in Sections 4 to 7, and behavioural testing of AI components.
AI behavioural testing covers accuracy against a task-specific evaluation set, and adversarial testing, deliberate attempts to make the system disclose what it should not, do what it should not, or exceed its intended scope. A system that has only been tested on well-behaved input has not been tested.
Findings are recorded with severity, and either fixed before delivery or documented as accepted risk with your agreement. Nothing is quietly closed.
9What you receive#
Every project ships with the following, as standard rather than on request.
The system itself: source code, infrastructure as code, and deployment configuration, in repositories you own.
Architecture documentation: how the system is put together, what depends on what, and why the significant decisions were made.
Threat model: what data the system touches, who can reach it, what happens if a component or the model behaves badly, and what we did about each.
Dependency inventory: a complete software bill of materials for every release, so you can check what is inside what you are running.
Build provenance: cryptographically signed records of how each artifact was built, verifiable with your own tooling. You do not have to take our word for what is in a release.
Security review record: how the system was tested against the standards in Sections 5 to 8, including anything we found and what we did about it.
Runbook: how to operate it, what to monitor, what the alerts mean, and what to do when something breaks.
Handover: a working session with your team, and the credentials and access transferred to you.
You own all of it. None of it is contingent on continuing to work with us.
10After delivery#
If you find a security issue in something we built, tell us at info@modulariti.ai. We will acknowledge within one to two business days, and give you an assessment and our intended action within seven to ten business days.
We extend safe harbour to security researchers acting in good faith: if you report a vulnerability responsibly, we will not pursue action against you for finding it. We do not currently run a paid bounty programme.
Where you choose the Run step (modulariti Care), ongoing maintenance covers dependency and model updates, monitoring, and response to issues as they arise. Where it does not, the runbook and documentation you receive are written so that your own team can carry the system without us.
Aligned withNIST SSDF (Respond to Vulnerabilities).
11Standards we align to#
We do not hold certifications against these frameworks. We use them because they represent the accumulated judgement of people who have studied these failures more closely than any four engineers could, and because building against a public standard means our work can be checked against something other than our own opinion of it.
OWASP Top 10 for LLM Applications (2026) and OWASP Top 10 for Agentic Applications (2026): the risk taxonomy for Section 6. Coverage is stated per item above, including where it does not apply.
NIST Secure Software Development Framework, SP 800-218: the structure for Sections 2, 4, 5 and 10.
NIST SP 800-218A: the generative AI profile of the SSDF, covering data governance and model-specific practice.
SLSA v1.1 Build Track: the yardstick for build integrity in Section 5.
Google Cloud Architecture Framework and CIS benchmarks: the reference for Section 7.
These are public documents. We encourage you to read them and hold us to them.
Changelog#
- v0.2Current
Internal review draft
- All open confirmations resolved except fine-tuning frequency (Section 6), which is left open deliberately.
- Section 5 now states SLSA Build Level 3 explicitly, with the verification mechanism named.
- Section 3 expanded: where we build, access, secrets, your data, project close, logging.
- v0.1
First draft
- Initial structure: eleven sections and a statement of purpose and limits.
modulariti.ai: Engineering Standard v0.2, 20 September 2026. Self-assessed; not audited.