A secure solution begins with a good design! Much of the foundation for assessing whether a solution is secure comes from the design phase, where important trade-offs between cost, benefit, and risk must be made.
The articles you find under the topic design on this page will focus on the design process. Although this process may include much more than we have listed, we cover the essentials such as thorough documentation of what is to be built, critical clarifications, and the need for context.
1 - Security Requirements
How can one build security into a solution if there are no well-defined security requirements?
Some requirements are implicit, such as the use of HTTPS/TLS, while others will be explicit and defined by customers or third parties. Even if the customer has no specific requirements, it is still important for the delivery team to create a list of requirements to ensure that the project’s framework is documented.
Most projects must adhere to various requirements from Bouvet, the customer, and external parties. All development teams must have control over the requirements that apply to the delivery:
From Bouvet (where applicable)
From the customer
Legal requirements
Legal requirements can include general requirements related to privacy, but many industries operate with more specific regulations that impose additional requirements.
In many cases, it is clear to both Bouvet and the customer what applies, but it is important that the team verifies this before starting to develop the solution to avoid costly and time-consuming surprises. Regardless of what is defined and where, the team should document the requirements they adhere to so that this information is preserved for the future.
Basic requirements
If no other security requirements have been defined, the security checklist can be a good starting point. It covers the major elements and can be completed by most teams without outside assistance. By using this checklist, the team gets an overview of the delivery status, including potential weaknesses and threats.
If the delivery requires a more thorough checklist, OWASPs Application Verification Standard (ASVS) might be a good alternative. This is a more comprehensive checklist that offers three levels of testing:
Level 1: Black box - all testing is done against the running system
Level 2: Everything from level 1, with additional checks targeting process, technology and the implementation.
Level 3: Thorough assessment covering all previous checks, as well as more detailed testing of the environment, architecture, and more.
Security requirements for AI systems
If the solution includes, or depends on, artificial intelligence (AI), additional requirements are needed beyond standard security requirements. AI systems introduce their own risk dimensions and these should be handled explicitly at the requirements level.
Security requirements for AI systems should cover:
Security: What model behavior is acceptable, and how should the system respond to anomalies? How is the system protected against misuse or manipulation?
Privacy and data use: What data does the AI system use for training or inference? How is personal data handled, and how do you ensure the system is not used for unintended purposes?
Monitoring and misuse: How should the system be monitored for abnormal behavior? What are acceptable use cases, and how is misuse detected?
Network is a fundamental component in everything we create, and it is important to have a basic understanding of how it works and how it can be exploited by others.
Correct network configuration matters in cloud, hybrid and on-prem alike. This page is meant as a short reference for secure network practice in project work.
Zero trust architecture
Zero trust means not blindly trusting internal or external traffic. Use the principle as your default: verify explicitly, grant as little access as possible, and assume compromise.
Minimum overview
Important
Keep track of which IP addresses and ports you expose, and which services are listening on those ports. Check firewall rules, look in the logs and scan your own systems with nmap.
Maintain an up-to-date overview of:
exposed IP addresses, ports and protocols
who can reach which services
why the exposure is necessary (the business need)
which rules are temporary, and when they should be removed
Network scanning
Scan regularly to confirm actual exposure. nmap is an established FOSS tool for discovering open ports and services.
Warning
The use of scanner tools such as nmap must always be cleared with the owners of the infrastructure and network. If you sit in a Bouvet office and scan a customer’s Azure environment, you can easily trigger alarms at both Bouvet and the customer, as well as at the ISP.
Isolating services
Important
Use a firewall to limit traffic within systems and between systems and the Internet. Use an allowlist where possible. Filter traffic at the application layer if necessary.
Practical ground rules:
deny by default on both inbound and outbound traffic
open only the necessary ports, protocols and known sources
avoid “Any” in rules
segment the network between functions and environments
use private endpoints or VPN where possible
place public services behind relevant security layers (for example WAF or API gateway)
AI services and network control
For AI solutions, your operating model should be evaluated against requirements for ingress and egress control.
AI in your own tenant (for example in Azure) usually gives better control over network boundaries, private endpoints, logging, and which systems can send data to and from the service.
AI as pure SaaS can provide faster startup, but often less control over network flows, allowed destinations, and traffic boundaries.
Minimum checks for both models:
which data can be sent in (ingress), and who can send it
which destinations data can be sent to (egress)
how traffic is logged, monitored, and blocked when anomalies occur
how privacy, data flow, and data residency/geography requirements are documented
Configuration
Network configuration should be automated as far as possible, preferably through CI/CD and infrastructure as code.
limit who can change network rules directly
use JIT access where possible
version the rules in source control
scan for deviations from the desired configuration and alert on unknown rules
document manual exceptions and put a time limit on them
Development projects use different environments for various purposes, such as testing deployments in a dedicated dev environment, exposing the test environment to product owners and other key personnel, and the production environment to end users. To avoid incidents in one environment affecting another, we must segregate them at a level that makes sense for the team and the context in which we work.
When we build solutions, we often set up multiple environments, typically for dev, test, and prod, so that we can develop while the product owner tests new functionality and end users use the system in prod. It is important to distinguish between these environments to avoid situations where changes in one environment affect the use of another.
When designing a new solution, we must consider how to separate the environments. For cloud services, a common approach is to use different subscriptions per environment where possible. One subscription cannot affect another unless explicitly configured, but there are other possibilities as well.
Common Segregation Patterns
Separate subscriptions per environment:
Natural separation unless explicitly defined access
More overhead with managing multiple subscriptions
Use of separate resource groups:
Simplified administration
Resource groups share some limitations and access at the subscription level
Separate virtual networks:
Segregation at the network level
Often requires more admin to ensure there is an actual separation
There are other approaches to this as well, but regardless of the solution the team chooses, it is important to consider the overall cost/benefit against the requirements to be met.
Segregation for AI systems
For solutions that include artificial intelligence or machine learning, infrastructure segregation alone is not always enough. Teams should also consciously separate data, models, and rollout practices across environments.
Separation of training, evaluation, and production data
Data used for training, evaluation, and production should be clearly separated. This reduces the risk of validating models on the wrong basis or allowing test and development activity to affect production-adjacent data.
Separation of model versions per environment
Models, weights, and related configuration should be versioned and clearly tied to the right environment. The production model should not be overwritten by experimentation in dev or test.
Gradual rollout of changes
When introducing new models or major changes, teams should consider mechanisms such as feature flags, controlled rollout, or other techniques that allow limited validation before full production rollout.
Authentication and authorization check respectively who you are and what you are allowed to do. These are important concepts that must be correctly implemented to ensure the security of a solution.
Authentication and authorization are crucial in all development projects. In short, authentication is about validating that a user represents the identity they claim to represent, typically by checking a username and corresponding password. Authorization is about checking that the user is allowed to do what they are trying to do. These are often abbreviated to authn for authentication and authz for authorization.
Authentication
When validating a user, the most important thing is to not create your own authentication solution! Ensuring that such solutions are actually secure is a huge task, and one should instead use established solutions for this!
Single sign-on is a common solution used to avoid having individual applications handling usernames and passwords in corporate environments. The user authenticates via a central platform or the operating system; every application the user opens will then run in the context of that session so that the users avoid manual logins. The user experience is streamlined as a result, and the users are ’trained’ to not having to log on. Any attempts to phish credentials will then appear as out of the ordinary and suspicious.
Common approaches for handling authentication can be the use of third-party services or protocols that handle authentication against the customer’s AD/Entra. In many cases, we want to use Single Sign-On (SSO) to avoid the user having to enter username and password, especially for internal business applications.
Common solutions for handling login are to use libraries that take care of the entire flow, such as Microsoft.Identity.Web. Other alternatives can be the use of:
SAML – An XML-based solution primarily used for Single Sign-On and authorization.
OAuth 2.0 – An authorization solution in which an identity provider (IDP) issues access tokens that are then checked and handled by OAuth.
OpenID Connect (OIDC) – An authentication layer on top of OAuth that enables retrieval of user and session information from the IDP.
Kerberos – An authentication protocol widely used in operating systems.
LDAP – An authentication and authorization solution used with various directory services, such as Active Directory.
It is important to understand the needs of the solution and which authentication methods are available and possibly desirable.
Authorization
The distinction between authentication and authorization is that authentication confirms who you are, while authorization checks that you are allowed to perform an action.
Similar to authentication, there are several approaches to how authorization is handled, and one needs to understand the best practices for the language and framework used.
There are still some main principles that should always be brought into the development process:
Default access should always be no access
This is also known as default deny or principle of least privilege, and is used to ensure that, for example, an unauthorized user does not have access to anything beyond what is explicitly allowed.
Authorization should always be checked
If a user attempts to perform an action, it should always be checked whether the user actually has access to this. Remember that this check must be made against the authoritative source for access rights, and never against data that the user can manipulate!
Users should always be given the least possible access
Also known as the principle of least privilege. A user should never be given more access than is needed to perform a specific task. This is done to reduce the attack surface if a user is compromised, so that the scope of damage can be limited.
Role-Based User Access
Using roles, role based access control (RBAC), is a common approach to granting user access. The goal is to define standard roles for an application so that access can be based on these. A common way to handle this, for example, with Entra or AD is to have:
access groups with all users. The access groups are added as members in
role groups, which are given access in the application.
This provides a better overview of who has access to what compared to users with individual access.
AI and agent access
For solutions with AI agents, it is not enough to control end-user access alone. The agent itself often acts as a separate identity with access to models, data, APIs, and tools. These access rights should be treated as high-risk when they are too broad.
Practical principles:
use a dedicated service identity for the agent; do not reuse user or admin accounts
apply least privilege per tool (tool access), so the agent can only call functions it actually needs
separate read, write, and administrative operations
limit access per environment (dev/test/prod) and per dataset or service
use time-limited or conditional access where possible
When an agent gets access to external tools or APIs, you should also control which commands, endpoints, and data operations are allowed. This reduces the risk that mistakes, misuse, or compromise have a large operational impact.
For MCP-based integrations (Model Context Protocol), the same principles apply, with extra requirements for clear boundaries:
each MCP server should have clear ownership and its own identity/service account
tools exposed through MCP should be explicitly scoped and authorized, not given broad, unrestricted access
the client should only get access to required MCP servers, and access should be revocable quickly
calls to MCP tools should be logged with who/what/why so misuse can be traced
Access management also affects operational risk: broad agent permissions make incidents harder to detect and increase impact. Changes to agent access should therefore be logged and followed up together with normal operational monitoring, see Logging and monitoring.
Threat modeling is an exercise where the goal is to identify threats in and around a solution. This makes it possible to identify and assess risk against the overall security posture of the solution. Based on a threat model, mitigating measures can be identified and implemented to reduce risk.
This is a brief introduction to threat modeling. Methods and tools are mentioned briefly, with links for further reading.
You may have already done simple threat modeling without realizing it. For example, have you ever thought about why the users of the system you’re creating need to log in with a username and password?
When these choices were made, you automatically performed simple threat modeling. You certainly don’t want unauthorized individuals to access data in your system, and you don’t want anyone to see the data transferred between your users and your website.
The whole point of threat modeling is to think like an attacker.
Identifying Threats
There are several ways to identify threats to a system. In practice, the most important thing is to involve the right roles, define what needs protection, and systematically review how the solution could be attacked or misused. Some threats may already be handled, while others require new measures. The process should be repeated when the solution, data flows, or usage patterns change.
A simple workflow is:
define the system boundaries and critical assets
identify threats and misuse scenarios
prioritize risk and decide on measures
verify that measures actually work
update the model regularly
Method Selection
Threat modeling is more important than which method you choose. Pick an approach your team can use consistently.
Workshop-based review: Low barrier and well-suited early in projects, in line with the principles of The Threat Modeling Manifesto.
Data flow + STRIDE: Useful when you want to review components, interfaces, and trust boundaries in a structured way; see OWASP Application Threat Modeling.
Attack trees: Useful when you want to analyze how a concrete attacker goal can be reached through multiple paths; see Attack Trees (Bruce Schneier).
Threat modeling for AI systems
For solutions with AI, looking at application code alone is often not enough. The threat model should also cover the model itself, prompt flow, data sources, evaluation basis, and how the system is used in operations.
Typical questions include:
which data enters the model, and who controls it?
which parts of the context are trusted, and which come from users or external sources?
what is the worst-case outcome if the model gives incorrect answers or is manipulated?
which security mechanisms exist around model calls, logging, access, and monitoring?
Some AI-specific threats that should be assessed explicitly:
Prompt injection: Input or documents attempt to override instructions or make the model perform unintended behavior.
Data poisoning: Training data, reference data, or evaluation data is manipulated so the model learns the wrong things or produces weaker decision support.
Model misuse: The system is used for purposes it was not designed for, or in contexts where error margins are unacceptable.
Leakage: Sensitive information leaks through prompts, outputs, logs, weight files, or surrounding integrations.
For AI solutions, it is also important to describe misuse scenarios, not only direct attacks. A model can be technically available and functioning, but still represent high risk if it is used for decision support without sufficient human control points.
From threat model to requirements and follow-up
A threat model has limited value if it is created once and then put away. Findings should be used to define concrete security requirements, testing needs, and operational controls.
For example, an identified threat can lead to a need for:
stronger authentication or access control
additional logging and alerting
validation of input and output
explicit limitations on use of a model or agent
regular review of datasets, prompt flows, or integrations
For AI systems, the threat model should also be used when assessing changes to models, data sources, prompt templates, evaluation sets, and monitoring. Changes here can introduce new threats even if application code is unchanged.
The threat model must be versioned and kept up to date. Once threats have been identified, countermeasures must be described, and their effectiveness assessed. A common approach is to give the threat a value indicating severity, for example, 1-10 where 10 is the worst. Countermeasures are assessed similarly but with the opposite scale where 1 has little effect and 10 (or up to criticality) has the highest effect. The sum of these gives a residual risk that indicates the remaining risk:
When a risk is identified, it is important that the risk owner is involved, as they are responsible for ensuring that the project delivers quality in line with expectations and requirements.
It is important that countermeasures are validated for them to be effective. The threat model should be reviewed regularly to see how the situation has changed, and if the total criticality or residual risk exceeds a threshold, consider measures to reduce them.
For systems in active operation, the threat model should also be used when deciding which events to log, what to monitor, and which deviations should trigger alerts. This is especially important for AI systems, where misuse, degradation, or unexpected model behavior can develop gradually over time.
More Information
Tools
Microsoft Threat Modeling Tool gives you a kick-start by describing common threats for various services. This tool is especially useful if you operate in Microsoft Azure.
It’s important to have a good foundation when building quality solutions, and drawings and diagrams showing the infrastructure, data flow, networks, and access control are crucial elements. Without this information, it is difficult to validate if the implementation matches the intended design.
When designing a solution, it’s essential to have clear and comprehensive drawings and diagrams that show the planned design. This is already done by many development teams without necessarily being a formal requirement, but it’s still worth mentioning here.
System diagrams should provide enough information to:
Validate that the implementation matches the design
Use them for threat modeling, pentesting, or similar activities
Be used by those managing the solution to get a good overview of components and data flow
Be used by the delivery team for onboarding new colleagues or handover to other teams
Although there is a lot that can be documented here, we focus on the most important aspects:
High-level system sketch with the main logical components
Detailed network diagram with resources, services, and networks
Data flow diagram showing how data flows between components in the solution
IAM diagram showing identities, accesses, and roles and where they are sourced from
Important dependencies – overview of other systems, services, resources, on-prem/cloud
Use of AI components
If the solution includes artificial intelligence or machine learning models, these should be explicitly documented in the system documentation:
In the data flow diagram: Show where training data and inference input come from, and how results continue through the system
In the network diagram: Document where the model runs (cloud API, edge device, on-prem server) and related network connectivity
In the dependencies list: Include model ownership, versioning, and where updates happen
In the IAM diagram: Show who can deploy, update, or monitor the model
Without this information, it is difficult to maintain a clear overview of risk, data flow, and compliance around AI components.
Examples
Below are examples of the points listed above. The diagrams you produce do not need to be identical; the most important thing is that they contain enough information to be used for their intended purpose and are understandable to the team.
To easily get started with designing diagrams and sketches, tools like Miro or Draw.io can be used. The latter is free and offers storage of drawings in the browser, locally on the machine as XML, and much more.
Keep in mind:
The diagrams do not need to be perfect or contain every conceivable detail. Assess the need and work on gradual improvements over time.
High-level System Diagram
This diagram should be a high-level introduction to the solution, showing all the major components and interactions between them.
Example of a high-level system sketch. It shows only the largest components and how they relate to each other. Dependencies outside the solution are dashed, so it is easy to see what the team controls itself.
Network Diagram
The goal of the network diagram is to show the network topology, with all the various virtual networks, subnets and resources or servers and firewall openings between them. A good network diagram visualizes the data flow between points for everyone to see, not just developers.
Example network diagram for a development environment. Every subnet is labelled with its address range, every resource has its own address, and the arrows show the direction of traffic and which port is open. The reporting workspace reaches the backend API through the same WAF as the frontend. The dashed box is a dependency outside the team's own environment.
Keep in mind:
Network diagrams should be created for all environments, providing necessary information on all resources in all environments, as well as connections between them.
Data Flow Diagram
The data flow diagram shows the data flow of the solution. This should include all direct dependencies not part of the project, so that it is possible to understand where data originates and all the nodes it interacts with.
Example of a data flow diagram. It follows the data from source to report and names the views, pipelines and schemas actually in use at each step. That naming is what makes the diagram useful when a discrepancy has to be traced back.
IAM Diagram
An IAM-diagram describes where users originate, and the roles and permissions assigned to users, services and devices on the various resources.
Example of an IAM diagram. Identities are on the left, scopes on the right, and every arrow is one role assignment labelled with the role name. Arrows ending on the edge of the subscription box are assigned at subscription level and inherit down to everything inside it; arrows ending on a resource apply to that resource only. The point is that no access goes undocumented.
Dependencies
This can also be drawn, but often a simple list is enough. This should contain all direct dependencies of the solution being developed, with a brief summary containing descriptions of what the team depend on.
On-prem database server production-sql-01
Uses three views maintained by the team
Data is imported via ADF
Company’s data platform, datalake datalake-somedata-prod01
Consumes datasets in the container production-data-container