We build systems that hold real business data: financial reporting, client records, payroll and rostering. Before you trust a consultant with that, you should know how they work.
This page sets out exactly what we do, in plain terms and without marketing language, so you can judge it rather than take our word for it. If your IT or security team wants to go deeper, we will happily walk them through any of it.
Last updated July 2026.
Continuous, not annual
Most problems in modern software arrive through the code you did not write. The applications we actively build and maintain are continuously scanned on three separate fronts, and findings are triaged rather than parked. Coverage is set deliberately per repository rather than assumed everywhere, and the full list of what runs where is further down this page.
Supply chain
Automated build steps normally reference third party tooling by a version label. Those labels can be repointed by whoever owns them, which means the code running inside a build pipeline can change without anybody approving it.
We reference every third party build step by an exact, immutable version instead. Updates still arrive automatically for review, but nothing changes inside our pipelines without a recorded, reviewed change.
Build credentials are also scoped to the minimum required. A pipeline that only needs to read code cannot write to it, publish anything, or reach production.
Credentials
A leaked API key is usually found after it has already been published. On the repositories we actively develop we turn on push protection, so a commit containing a recognised credential is rejected at the point it is pushed rather than flagged once it is already in history.
Client credentials and connection details are held in managed secret storage provided by the hosting platform. They are never committed to source control, and they are not shared between unrelated systems, so an issue in one environment does not widen into another.
Change control
On the applications we run for clients, the production branch is protected by a rule rather than by convention. Changes cannot be pushed to it directly: they arrive as a proposed change and must pass an automated gate covering linting, type checking, tests and a full build. On the production applications we own and operate, an unsigned commit cannot merge at all, so authorship is cryptographically provable rather than self declared.
Substantive changes then go through an independent adversarial review, where a second system is tasked specifically with disproving the claims made about the change. Findings are answered one by one, in writing, and the review record is committed alongside the code. A change ships only once that review returns clean.
We keep that record because it is the part that matters. A review process is only worth something if it regularly finds things, and ours does.
Access
The client facing applications we run in production authenticate against Microsoft Entra ID. Access is per person, checked against an allow list on every request rather than only at sign in, so removing someone takes effect immediately instead of whenever their session happens to expire.
That also means every action is attributable to a named person, and multi factor authentication is enforced by your own Microsoft tenant rather than by us.
We will say plainly where that is not yet true. Applications still in pre release testing sit behind an interim access gate so a client can review the work before launch, and moving them onto per person identity is part of shipping them, not an afterthought. If a system you are relying on is in that state, we will tell you before you ask.
Sign in routes and public endpoints get rate limited, which bounds both credential guessing and runaway cost. Where firewall rules front the application those limits run at the network edge before any of our code does; elsewhere they run inside the application against shared state, so one limit holds across every server instance instead of one per process. Coverage is set per application rather than assumed everywhere, so it is another thing we will tell you the state of for yours rather than let you guess.
Your environment
Most of our work is built inside your own Microsoft tenant: your Fabric workspaces, your Power BI capacity, your storage. Your data does not move to us, and it is not copied to a third party platform to be worked on.
Where we need access, we use an account you issue, governed by your own identity provider, your own multi factor authentication and your own conditional access policies. You grant the minimum access the work requires, you can see what it did, and you can revoke it in one place the day an engagement ends.
Everything we build is delivered as source code you own, in a repository you keep. There is no black box and no lock in. If you part ways with us, the work and its full history stay with you.
Reporting
The most common mistake in business reporting is hiding a figure on a page and calling it secure. Anyone who can connect to the underlying model in Excel, or export the data, or build their own report against it, walks straight past that. Hiding is presentation. It is not access control.
Where a model holds data that not everyone should see, we apply security roles inside the semantic model itself, so the restriction travels with the data. It applies to every report built on that model, to Analyse in Excel, to exports and to anyone querying it directly.
Depending on what the data calls for, that is either an access gate, where a user without the role sees nothing at all even if they can otherwise build reports in the workspace, or a row filter that narrows each user to the records that are theirs to see.
We apply it where the data warrants it rather than everywhere. Restricting a model that everyone is meant to see adds maintenance and a false sense of control without protecting anything. Deciding which models need it, and on what basis, is part of the design work rather than a switch flicked at the end.
Membership is driven by your own Entra security groups rather than named individuals, so access follows your existing joiner and leaver process instead of becoming a list somebody has to remember to update. Each gated model has a written access request and approval path, so there is a record of who was granted what, and why.
AI in our workflow
We use large language models as part of how we work, and we would rather tell you that plainly than have you discover it. It is also the question we get asked most often, so here is the specific answer rather than a reassuring paragraph.
Two models are involved. One writes and reviews code with us. The other is given the finished work and told to attack it, which is the independent adversarial review described further up this page. Using two vendors is deliberate: a reviewer that shares a model's blind spots is not really a second opinion.
Claude, by Anthropic.
Used for building and for our own first pass review. We hold a commercial Team plan, whose terms exclude training on customer content.
Grok, by xAI.
Used as the independent adversarial reviewer. On a paid plan with the model improvement setting switched off, so conversations are not used for training.
On both, the setting that would let our work be used to improve someone's model is off. We check it rather than assume it, because on consumer tiers that setting is usually on by default, and a subscription changing plan is exactly the sort of thing that would quietly flip it back.
What this does not mean: that no data ever leaves your tenant, or that nothing is stored. Code and query text are sent to those providers to be processed, the same way they are sent to a hosting platform or an error monitoring service, and both providers retain conversation history for a period before purging it. What the setting controls is narrower than that, and worth being precise about: the work is not added to a training corpus. Retention windows, human review of flagged content and the provider's own subprocessors are separate questions, and if your security team wants those answered we will point them at each vendor's terms rather than paraphrase them here.
We also keep humans accountable for the output. An AI wrote none of this on its own authority: every change is reviewed, every claim on this page was checked against the live systems, and a person signs the commit. If a model gets something wrong, that is our mistake, not the tool's.
How we think about it
No engineer worth hiring will tell you a system is perfectly secure. Automated analysis finds the categories of problem it has been taught to look for, and a clean report describes today rather than guaranteeing tomorrow. Anyone who tells you otherwise is selling you something.
So here is the commitment instead. The controls on this page are switched on, applied consistently to the systems they are relevant to, and verified rather than assumed. When something is found, it is fixed and the finding is written down. When we get something wrong, the review process catches it before it ships, and that is precisely why we run one.
That is the standard we hold our own systems to. It is the same standard we apply to yours.
For your IT team
If your security team wants to tick boxes against a questionnaire, these are the features we operate, grouped by the platform that enforces them. Coverage is set per repository rather than blanket: the applications we build and run in production carry the full set, while older or handover projects may carry a subset, and a repository holding only report definitions has nothing for code analysis to read. We would rather tell you exactly what is switched on for your own work than claim a number that does not survive checking.
Our public organisation is at github.com/Streamline-Analytics.
Responsible disclosure
If you believe you have found a vulnerability in anything we run or have built, we would rather hear from you than not. Email us with enough detail to reproduce the issue and we will acknowledge it as quickly as we practically can, and tell you what we intend to do about it.
Two asks: leave other people's data alone while you are looking, and give us a chance to fix it before you go public. Report something in good faith and you will hear nothing from us but thanks.