Start with a threat review
Every project begins by asking what the product must protect, who might attack it, and how. We list the assets (accounts, payments, personal data), the entry points and the likely attackers, then decide which defences the design needs. This is threat modelling. It costs little in the first week and a lot after launch, which is why it comes first. Our article on threat modelling for small teams shows the approach in plain terms.
Secure coding practice
Everyone on the team learns threat modelling and secure coding, whatever their role. In code, that means working from the OWASP Top 10 list of common web risks, choosing safe defaults, keeping security-sensitive code small and readable, and avoiding home-made cryptography. The secure by default checklist and our guide to secure app development go further.
Authentication and access control
These are two questions: who are you, and what may you do? We treat them separately.
- Authentication: passwords are never stored in plain text. We use an established identity service or a slow, salted hashing method, support multi-factor authentication where the risk justifies it, and design sessions to expire and to be revoked.
- Authorisation: the server checks permissions on every request, not only on the screen. Access is denied by default, and we test that one user cannot read or change another user's data by changing an identifier.
- Least privilege: each role, service and API key gets only the access it needs.
Input validation
Everything that arrives from outside is untrusted: forms, URLs, files, headers and API calls. We validate it on the server against what is allowed, use parameterised queries against SQL injection, encode output against cross-site scripting, and limit the type and size of uploads. A content security policy adds a second layer in the browser.
Secrets and configuration
Passwords, API keys and tokens do not belong in source code. We keep them in the secret storage of the hosting platform or cloud provider, separate for each environment and with the least access that works. A leaked key can then be rotated without changing code, and a test environment cannot reach live data by accident.
Dependency and cloud checks
Modern products are mostly other people's code. We scan dependencies for known vulnerabilities, pin versions with lock files, and update on a routine, not only after an incident. For the cloud account (AWS, Azure, Google Cloud, Vercel or Cloudflare), we review the configuration for common mistakes: public storage, over-broad roles, missing logging and exposed admin interfaces.
Code review
Changes are reviewed by a second person before they merge, with extra attention to anything touching sign-in, permissions, payments or personal data. For an inherited or existing product, a secure code review reads the risky parts line by line.
Testing before every release
Each release is tested before it ships. Automated tests cover the rules that matter for security, such as who can see what, alongside ordinary behaviour. The release pipeline (CI/CD) runs the checks the same way every time, including the dependency scan. Riskier changes also get a manual check by a person.
Security review before launch
Before a product goes live we review it as a whole: the threat review is revisited against what was actually built, the main flows and the configuration are tested, and the findings go into a prioritised fix list.
| Priority | Meaning | Usual handling |
|---|---|---|
| Critical or high | Could expose data or let someone take over accounts | Fixed before launch |
| Medium | Weakens defences, or is hard to exploit | Fixed before or soon after launch, agreed with you |
| Low | Hardening and good-practice improvements | Scheduled on the roadmap |
You decide with us what must be closed before launch. Where a deeper, attacker-style test is needed, penetration testing is scoped as separate work. See penetration test or vulnerability scan for the difference.
What we ask of you
- Access hygiene: a named account for each person, no shared passwords, and access removed when someone leaves the project.
- Multi-factor sign-in on the accounts that matter most: cloud, code repository, domain registrar, email and admin panels.
- A named release approver: one person who approves each release, so nothing goes live by accident.
- News of changes: a new integration, kind of data or user group changes the threat model, so tell us early.
- Prompt decisions on the fix list, so critical items do not wait.
If a vulnerability is found in your product
Whoever finds it, we follow the same order. We tell you promptly and privately. We confirm it and assess how serious it is and who could be affected. We propose a fix and a way to verify it, agree when to release it, and afterwards look for the same weakness elsewhere in the product. Whether to notify users or authorities is your decision with your own advisers; we supply the technical facts. Response times are agreed in writing per project.
Our own disclosure policy
If you find a problem in the Asphaleia website or in a system we operate directly, our vulnerability disclosure policy explains how to report it and what to expect. Client systems are out of scope unless the client has agreed.
This page describes our method. It is not a certification or an audit report, and it is not legal advice. The specific controls for your project are agreed in writing.