This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Design

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?

For detailed implementation guidance, see Using Artificial Intelligence.

More Information

2 - Network Concepts

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.

Proper configuration of the network is important for pure cloud solutions, hybrid networks, and on-prem solutions. Network is a vast field with significant variations in usage, security, and complexity. Below we cover basic concepts for communication to and from servers and network services.

Zero Trust Architecture

Zero trust is an important concept in network operations. In short, you should never trust anything coming from other systems, and you should assume that all communication will be compromised. Zero trust cannot be solved just by securing the network, but must be a goal in itself when designing solutions and the infrastructure around them. By implementing zero-trust, you will eliminate many potential attack vectors and thus protect the services that use the network.

Getting an Overview of the Network

Important

Keep track of which IP addresses and ports you expose, and which services are listening on the ports. Check firewall rules, look in logs, and scan your systems with nmap.

Keep an overview of which IP addresses, ports, and protocols an IT system exposes to the outside. This applies regardless of whether you are setting up a new system, changing an existing one, or just investigating what you already have. A targeted attacker will map open endpoints to find targets, and there have been several examples of data breaches starting with a forgotten, insecure service.

As developers and system managers, it is critical that we know exactly which services are open to whom and why.

When setting up new systems, you have good opportunities to control what is exposed. The main rule according to the Zero Trust architecture should be to start with everything closed, and then open only the ports and protocols that are needed. New components should be isolated from existing systems.

In existing systems, it can be difficult to get an overview of what is exposed, especially in hybrid or on-prem setups. Simply shutting down everything that is not documented can also be risky, as this can affect legitimate systems. If working in the customer’s infrastructure, feel free to contact the network department for help with mapping.

Network Scanning

To find open ports and services, you should scan both public and private IP ranges from different locations. Remember that internal networks can follow different routes than external traffic and thus see different openings. The same applies in situations where you have office networks, VPN, DMZ/guest networks, or other open networks.

There are tools and services that make mapping easier. nmap is the industry standard and FOSS, and it is excellent for scanning IP ranges and detecting open UDP, TCP, and SCTP ports. If you lack an overview, nmap is a good place to start.

Caution

The use of scanner tools like nmap must always be clarified with the owners of infrastructure and network. If you are at a Bouvet office and scanning a customer’s Azure environment, you can easily trigger alarms at both Bouvet and the customer, as well as the ISP.

Service Isolation

Important

Use a firewall to restrict traffic within systems and between systems and the Internet. Use allowlist if possible. Filter traffic at the application layer if necessary.

Firewall is a common term for barriers in a network that stop unwanted traffic. In most contexts, the definition is a bit narrower, referring to barriers at the TCP/IP layer, but a firewall can also operate at the application layer.

To enforce a zero-trust architecture, all components must be isolated and only made available to the services that they themselves will consume or deliver data to. This makes it necessary to have a firewall between components in the same application, between applications, and between the application and the Internet. If you have an application with a database, a backend API, and a web API, it is advantageous if you can set firewall rules between the components that only allow the necessary traffic. See the diagram below for an example.

Firewalls should always drop all incoming and outgoing traffic by default and be explicitly opened for legitimate connections. Always limit port openings to specific ports and protocols where possible. Avoid using “Any” as the protocol!

Also use firewalls between all services within the network to ensure multiple layers of protection if one fails. Segmenting the network so that each function has its subnet will also help.

Avoid sending traffic over the internet even to your own cloud services, use private endpoints and VPN tunnels where possible. Services that must be exposed to other systems (both internal, external, and on the internet) should be placed behind security functions such as web application firewalls and/or API gateways, and you must ensure that these also protect against, for example, DDOS attacks.

Route all outgoing traffic through a dedicated proxy service that blocks everything by default, allowlisting as needed. Never expose services directly if you can avoid it. Exposing services on ports other than the standard ports is not a good idea; a network scan will quickly reveal this.

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 much as possible, preferably using a CI/CD system.

  • Limit who can configure both the network and network rules directly
    • Set up Just-in-time (JIT) access where possible
    • Limit where the network can be edited from (e.g., only from inside an on-prem firewall)
  • Script all rules that can be scripted
    • Use source code control
      • Have extra security on repos containing the network source, protecting both reading and writing
    • Use tools like Snyk to run analysis of scripts
    • Scripts should be run regularly and automatically (at least daily)
      • If unknown rules are detected, alerts should be created
      • All unknown rules should be deleted or disabled
      • Alternatively, other methods can be used to detect deviations from the desired configuration
  • Back up or document all rules set up without scripting
    • Document all rules set up/handled by people outside your team

More Information

3 - Segregation of Environments

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.

More Information

4 - Authentication and Authorization

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.

More Information

5 - Threat Modeling

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.

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:

Identified Threats          Criticality     Countermeasures Residual Risk
Threat  1                   8               8               0
Threat  2                   2               0               2
Threat  3                   4               3               1
Total                       14              11              3

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.
  • OWASP Threat Dragon is a similar open-source tool worth checking out.
  • Draw.io with this package drawio-threatmodeling is a tool available both on the web and in common clients.
  • OWASP pytm is an open-source framework for threat modeling as code in Python, useful for teams that want to version models together with source code.

Cards and Workshop Aids

  • LINDDUN GO is an accessible card-based method for privacy threats, with a free PDF deck and digital version.
  • OWASP Cornucopia is an established, free card deck for deriving security requirements in development projects.
  • Elevation of Privilege (EoP) is a classic threat modeling card deck by Adam Shostack, available as open resources.
  • The Security Cards from the University of Washington is a practical brainstorming set with printable cards.

Courses and Lectures

Other Sources

6 - System diagrams and drawings

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.

Overordnet skisse

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.

Nettverksdiagram
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.

Dataflytdiagram

IAM Diagram

An IAM-diagram describes where users originate, and the roles and permissions assigned to users, services and devices on the various resources.

IAM-diagram

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
    • Lineage is visible in Purview
    • Uses only datasets approved by the data owner

More Information