Queensland Government

Secure software development and delivery guideline

Document type:
Guideline
Version:
v1.0.0
Status:
CurrentNon-mandated
Effective:
November 2026–current
Security classification:
OFFICIAL-Public
Category:
Cyber security

Purpose

Developing and delivering secure digital solutions is critical to provide safe and reliable government services to the public, and to protect sensitive information. This guideline is intended to assist Queensland Government entities understand key concepts, processes, and techniques that enable the production of digital solutions that are resistant to malicious interference and therefore reduce Queensland Government cyber risk.

Overview

Secure software development and delivery is necessary to enable the Queensland Government to protect its sensitive data, including the data that it stores on the behalf of its employees, suppliers, and the citizens of Queensland. It is also necessary to ensure that the Queensland Government can deliver cost-effective and reliable public services, and to maintain the overall trust and confidence of the public.

Cyber adversaries are constantly attempting to find and exploit software vulnerabilities to compromise these systems for their benefit. These adversaries use automation technology, including artificial intelligence, to accelerate their malicious activity. Secure software development and delivery assist the Queensland Government defend against this threat and reduces the likelihood of major financial loss, service failure, and reputation damage.

Secure software development and delivery is not merely a technical requirement for information technology (IT) and operational technology (OT) solution development and operations. Executives, leaders, and other IT professionals at every level in the Queensland Government play a role in achieving positive cyber security outcomes. Adopting the guidance provided in this document, will help Queensland Government entities achieve the following benefits:

  • Satisfaction of increasing customer expectations: Queenslanders expect that their sensitive information will be handled securely. A security breach can erode public trust of the entity, and the Queensland Government overall. When the public loses trust in the use of digital service channels, they resort to visiting physical customer service centres in person to conduct transactions, which is more costly to the Queensland Government and inconvenient for its citizens.
  • Avoidance of costly incidents: Security failures can lead to high recovery costs, legal liability, extended service downtime, and reputational damage. Taking preventive measures upfront to avoid a major incident is much less costly than dealing with the fallout of a serious security incident.
  • Enablement of innovation: The use of secure development and delivery practices enables an entity to innovate with IT to achieve business objectives without fear of introducing software vulnerabilities that lead to losses and service failure. The use of these practices typically results in higher quality digital solutions with a lower total cost of ownership.
  • Satisfaction of contractual and regulatory compliance requirements: Security is often part of organisational, contractual, and regulatory obligations. Proactively addressing cyber security will ensure that your entity will continue to meet compliance stakeholder expectations and legal requirements at the lowest cost.

Content summary

Modern software delivery pipelines are attractive targets for attackers. Compromise of source code, build systems, or deployment infrastructure can lead to supply-chain breaches, intellectual-property theft, and regulatory exposure. This short summary of the enclosed guidance outlines controls and best practices to safeguard every stage of the software development environment – from coding and build automation to testing and deployment.

Enablers of secure software development and delivery

This section highlights the interdependence between organisational culture, people, processes, and technology. Interdependence is required to achieve secure software development and delivery, and more cyber resilient Queensland Government entities. By addressing these four dimensions holistically, entities can:

  • reduce risk and losses
  • improve business efficiency
  • even foster innovation.

They can also maintain compliance with legal and regulatory obligations, and continue to maintain the public’s trust.

Consider security from the start

By making cyber security a fundamental consideration early during project planning, an entity:

  • improves solution quality
  • reduces cyber risk
  • avoids costly rework to remediate security defects.

When considering the delivery and maintenance of technology solutions, it’s much cheaper and easier to address cyber security during the requirements, design, and development, phases of solution development, rather than to reactively address problems that are detected later in the delivery process, and especially after the solution has been deployed into production.

Consider:

  • explicitly defining security requirements into the overall set of solution requirements
  • confirming these requirements are being met throughout the development and delivery process (certainly before production release).

Developing a standardised set of security requirements, patterns and architectures, that are applicable to your entity’s specific technical environment and are reusable across initiatives, will also help reduce the overall cost of secure development and delivery.

Produce consistent and comprehendible code

Code that is poorly written, inconsistent, or undocumented, increases the overall complexity of a system, which makes it more difficult to ensure that security issues have been properly addressed. Complexity can obscure defects that introduce vulnerabilities. It then makes it difficult for the defects to be detected and corrected during the development process. Naturally, this task becomes more difficult as the codebase increases in size and complexity. Promote the value of clearly written and well-structured code to understanding of the code base. This reduces the risk of obscured security defects and can expedite routine software maintenance, reducing cost.

Create or adopt secure design patterns and a consistent coding style. These can help ensure that the codebase is readable, maintainable, and even self-documenting. Supplementary materials, such as security specifications and standards, the creation of associated test cases for integration into development pipelines, and performing regression testing, should evolve alongside solution development to provide additional assurance.

Key sources of complexity include poorly structured software architectures, classes or variables with confusing or ambiguous names, inconsistent file organisation, and the introduction of different coding styles among individual team members. Other issues include insufficient software documentation, such as inline comments or system design artefacts, and coding without consideration for subsequent testing or validation.

Addressing these issues through a requirement for well-defined coding standards, and a strong culture of adherence, ensures a logical and readable codebase as the solution evolves and is maintained over time. Where available, language and industry-based coding standards should be considered and ideally used during the software testing process to ensure compliance.

Responsible use of AI in software development

The use of AI-enabled software development solutions may increase productivity by generating code automatically. These solutions may be delivered as stand-alone products or web sites/services. They may also be integrated into new or existing software development environments (SDEs) or be accessible by other means. The use of these tools introduces security risks into the software development and delivery process that must be managed for the tools to be used safely.

AI-enabled software development tools in the hands of competent and experienced developers may increase productivity and result in code with less security defects. However, AI-enabled tools are not yet capable of always producing code that is totally free of security defects or may produce code that is inappropriate for the solution architecture. When these tools are used by inexperienced or incompetent developers, and the code that is generated is not actually understood by the developer, security defects and other problems can arise.

Consequently, the code that is produced must be reviewed, and formally approved, by experienced, security-knowledgeable, software engineers before inclusion into any entity digital solution under development. This requirement is even more important when producing software that will form part of:

  • multiple software solutions, for example libraries and other software dependencies
  • solutions where exploited security defects can result in catastrophic outcomes.

Another risk of the use of AI-enabled software development tools is the potential loss of an entity’s sensitive information. An inexperienced or careless software developer may include intellectual property, access control tokens or passwords, encryption artefacts, or other sensitive information within their code that later becomes accessible by the AI-enabled tool, potentially to unauthorised parties. As with any information submitted to an external service, a copy of the information both may be stored within the service’s repository in some form, which may later be extracted by cyber adversaries using innovative techniques.

  • Some AI-enabled tools have inherent protections to safeguard against the extraction of an entity’s sensitive information or can be configured to prevent this. Unfortunately, many do not. Consequently, the use of AI-enabled software development tools by an entity should be conditional upon the risks being investigated, documented, then effectively mitigated, with the residual risk level being formally accepted by entity management.
  • Do not paste secrets, tokens, customer data, proprietary algorithms into AI prompts.
  • The use of masking scripts or safe prompt wrappers that automatically redact dangerous content may be helpful albeit not always reliable. Implementing other guard rails, such as non-deterministic methods to ensure expected outcome and implementing mechanisms for continuous monitoring can help mitigate the risks.
  • Configure enterprise-grade AI features to prevent an AI system from training itself with an entity’s code base or storing an entity’s software artefacts in clear text, especially within logs that can be accessed without entity authorisation.
  • Only use AI-enabled tools that have been security assessed and approved by your entity.

Address the risks of using externally sourced code

The productivity of most software developers is dramatically increased via their acquisition of externally sourced code, which is often referred to as a 'library', 'package', or 'dependency'. By utilising externally sourced code to implement a component of a solution, a developer avoids having to write their own code to produce the same component. Unfortunately, cyber adversaries are aware of this practice and can exploit it for their malicious purposes. The software supply chain is now under continual threat.

For example, cyber adversaries can covertly introduce malicious code into an external repository. This then becomes a part of the entity’s solution once the entity incorporates the external repository into the entity solution under development. Whenever externally supplied software is under consideration for entity use, a record should be kept describing:

  • why the software is believed to be trusted
  • what actions are required to mitigate the risk
  • what impacts will occur should a security issue arise
  • what actions will be required if this trust is breached
  • who compiled the record
  • who approved the decision to proceed.

Entities can restrict the use of externally sourced code to those sources deemed trustworthy, or low risk. This is an external source that:

  • has a long history of responsible software management
  • provides code that is widely used globally
  • promotes their own secure software development practices
  • has a demonstrated rapid response to reported security defects will introduce a lower risk than an external source that is
    • new or unproven
    • only used by a small number of other organisations
    • does not implement secure development practices, and
    • is non-responsive to reports of security defects.

An entity can accurately track its use of externally sourced code. Tracking information, which is often represented in a machine-readable format called a software bill of materials (SBOM), is highly useful when security defects become known to the software developer community. When an entity’s software developers become aware of the defect, they can use the SBOMs to rapidly determine if they have produced, or operate, software that includes the defective code, and what action to take. This activity can dramatically increase the speed that an entity can remediate the defect, which reduces the time that an adversary can exploit the defect.

Entities should ensure that all externally sourced code receives a security review by a security-knowledgeable developer, and is analysed by security testing tools, before being allowed to be incorporated into an entity’s IT solutions. The mitigation activities should be considered essential in situations where exploited security defects can result in significant adverse outcomes.

Ensure secure failure modes

A secure failure mode (or fail closed mode) is a design principle where systems default to a secure state when an error or unexpected condition occurs. Instead of maintaining availability at the expense of security, the system denies access or halts operation until the fault can be safely resolved. This approach prioritises confidentiality and integrity over convenience or uptime and is appropriate in many scenarios. For example, if an authentication service fails to connect to its identity provider, a fail-closed system will reject all login attempts rather than allowing unauthenticated access. The goal is to prevent accidental or malicious exploitation during periods of degraded operation.

Failing securely ensures that a system’s security boundaries remain intact even when dependencies break, or inputs behave unexpectedly. Adversaries often look for failure paths such as timeouts, exceptions, or dependency failures, that cause systems to revert to permissive behaviour. By explicitly defining how components respond to failure, developers eliminate ambiguity that might result in unvalidated data being accepted or unauthorised users gaining access. This mindset treats failure as a potential attack vector, ensuring that no data is exposed, modified, or processed insecurely when components malfunction.

Some examples include:

  • when writing access-control mechanisms, always initialise authorisation states to false or denied. This ensures that if the validation logic crashes midway, the user is locked out rather than granted access
  • when handling application errors like a dropped database connection or an API timeout, catch blocks should terminate the current process or transaction and throw an exception rather than silently bypassing the failure
  • fail-secure software protects information boundaries when a crash occurs. A system failure should never leak operational context to the end-user. Log highly detailed contextual information, for example, stack traces, database query errors, memory dumps, and so on internally to a secured logging server. Present the public user with a generic, sanitised error identifier, for example 'An unexpected system error occurred. Reference code: ER3465'
  • when secondary systems or microservices experience a severe outage, implement 'circuit breaker' patterns that fall back to static, safe functionality rather than leaving endpoints exposed. If an external authorisation provider or database goes offline, the software should automatically downgrade into a restricted, read-only mode, rejecting all data manipulation requests until the service safely recovers
  • ensure the CI/CD pipeline runs negative test cases. Test passing invalid inputs, mock database drops, or malformed authentication tokens to verify that the software responds by rejecting the interaction rather than breaking open.

While failing securely protects against unauthorised access and data corruption, it can impact availability, especially in distributed systems or high-availability environments. Therefore, architects must design systems that are both resilient and secure under failure. This often involves redundancy, health checks, and circuit breakers to ensure that security enforcement points like authentication, encryption, and access control, are reliable and can fail independently without compromising protection. Ultimately, designing for secure failure means recognising that availability can be restored, but a loss of confidentiality or integrity cannot be undone, and then building systems accordingly.

The entity’s software development and delivery methodology should capture the concept of solution 'survivability', which recognises that the operating context for most software must be considered hostile. Entities should ensure that their software development practices assume the omnipresence of adversaries. This includes practices that confirms the integrity of builds, for example by digitally signing legitimate artefacts, and by 'failing secure' if the software is malfunctioning.

Secure the development environment

Malicious software can cause significant financial and reputational damage to a Queensland Government entity and can even cause risks to human safety. An entity’s employees who use IT systems can be tricked into assisting cyber adversaries by inadvertently introducing malicious software into an entity’s IT environment. In response, modern enterprise IT environments include controls that prevent standard users from writing and executing their own code, and from executing code obtained from external sources, either deliberately or accidently. As standard IT system users have no work requirement to write and deploy code, these restrictions typically pose little to no inconvenience to the entity.

However, these same restrictions are impractical for an entity’s software developers. Writing code, and obtaining code from external sources, and then executing code, for example as part of testing and deploying new services, is an inherent part of their role. Cyber adversaries are fully aware of the extra system access, and powerful capabilities, provided to entity’s software developer. So, they consider these developers as attractive targets. Compromising the account of a software developer is often a first step of a malicious process that can result in significant losses to an entity. The following sections describe steps that entities can take to address this threat.

Address flexibility and security trade offs

Firstly, the performance of a software developer is often evaluated by the developer’s productivity in writing code to build or extend IT solutions. Consequently, it is important to ensure that those security controls and processes put in place to protect the developer’s digital work environment interfere as little as possible with their software development and delivery practices.

Securing a development environment requires:

  • understanding the risk context
  • applying appropriate technical controls
  • ensuring trust and verification of legitimate usage.

The line between development and operations is becoming increasingly blurred. This overlap means that a compromised development device could have significant and direct downstream impacts on services. Implementing risk-appropriate controls to limit this exposure is important.

A compromised development environment can lead to several risks, including theft of sensitive information such as encryption keys, passwords, and intellectual property. Compromise can also result in the insertion of malicious code into the source code base for IT solutions under development or maintenance. Compromised devices can be used by an adversary to:

  • attack the build and deployment pipeline
  • gain a foothold into the wider entity IT environment
  • gain insight into sensitive applications as a precursor to further attacks via other means.

Users of standard business services like email, document storage, and routine business applications, are targets of cyber adversaries. Software developers are often users of these same standard business services. For these software developers, logical separation of their development environments from their access to standard business services impedes adversaries who are successful at compromising the standard business services from then moving laterally to then gain additional unauthorised access the development environment.

To further address these risks, an entity can apply the following additional practices.

Monitoring the development environment

In mature IT organisations, certain system access provided to, and tasks performed by, system administrators are monitored, which allows for:

  • user access and activity reviews
  • incident response processes to be initiated.

Consider similar tracking of select developer actions that might indicate compromise and malicious activity.

Tools can be used to control, monitor, and report, on each time that a developer performs a task that requires administrative access. The benefit of these tools is that they can track these high-risk tasks and ensure that developers only receive the permissions necessary. Examples include:

  • token creation – generating authentication tokens that grant access to systems or code
  • repository visibility changes – switching a code repository from private to public (or vice versa)
  • force pushes – overwriting commit histories in a shared repository, which can destroy or alter code
  • GitHub App installations – adding third-party integrations that may require extensive permissions and impact the CI/CD process
  • GitHub Actions workflow edits – modifying automated CI/CD build pipelines, which could introduce malicious deployment steps if compromised.

When a developer changes projects or role, or ceases to be employed by an entity, the tool ensures that all unnecessary permissions are immediately revoked. By providing the right tools and environments, entities can empower developers to work productively while ensuring a secure posture.

Advanced tools that perform user and entity behaviour analytics (UEBA) can help identify unusual or risky behaviours, such as accessing sensitive systems at odd hours or attempting to upload or download large volumes of data. These tools use machine learning to establish a baseline of normal activity and flag deviations for further investigation. By combining trust with robust verification mechanisms, entities can strike the right balance between security and productivity. If your entity operates a SIEM solution, consider requesting that logs of important developer and administrator actions be ingested into the SIEM to assist with anomalous event detection.

Even with robust security measures, compromises will occur. Preparing for this eventuality involves proactive threat modelling to identify potential attack vectors and to assess the impact of a compromised development environment. This should be complemented by an incident response plan that addresses:

  • the most likely types of compromises anticipated
  • what action to take
  • whom to inform.

Reduce the attack surface of the developer environment

Minimising the attack surface of development environments can reduce the likelihood of exploitation. Segregating development, testing, and production, environments are important to minimise lateral movement and prevent malicious software active in one environment from reaching the others. Other techniques include running development workloads inside isolated virtual networks, using hardened base images for build servers, and disabling unused services or open ports. Effective data management practices, such as ensuring that sensitive data is anonymised or desensitised where possible, can limit the value of stolen data to attackers.

Containerisation and ephemeral build agents can help ensure that each build starts from a known-clean state and is discarded when finished. This leaves no persistent environment for an attacker to exploit. Regular patching and configuration management automation using dedicated software tools such as Ansible, Chef, or Terraform can help ensure systems are configured consistently and securely every time they’re built. One cannot steal what no longer exists.

Infrastructure as code (IaC) refers to defining infrastructure setup, for example servers, networks, build agents, and so on, using code, so one can automatically rebuild environments with the same secure baseline every time. This consistency helps prevent “configuration drift” where systems slowly diverge from secure standards due to manual modifications. An adversary’s processes to maintain a foothold in a target environment can be frustrated by regularly generating “greenfield” virtual infrastructure as part of software builds. Logically segmenting the development environment can increase overall security by requiring an adversary to have to breach many controls to move laterally to access the entire environment.

Automating and codifying infrastructure setup keeps every build environment securely patched and consistent across the entity. By addressing these issues, entities can create a more resilient development environment with fewer opportunities for attackers to exploit. Ensure that CI/CD and other build processes remove all temporary artefacts promptly after use.

Protect access credentials and secret keys

Privileged Identity Management (PIM) refers to managing and controlling privileged identities, namely those accounts with elevated permissions that can access sensitive systems and data. PIM solutions provide a way to grant just-in-time, time-bound, or approval-based, access to critical resources. Privileged rights are granted only when needed and for a limited duration. Requests for privileged access often require managerial or security-team approval. All privileged activities are logged for compliance and security monitoring.

Privileged Access Management (PAM) is a broader discipline for securing, controlling, and monitoring privileged access to critical systems. While PIM deals with identities, PAM focuses on the access and sessions themselves. PAM solutions store and rotate credentials for privileged accounts such as root or admin accounts. PAM solutions also record administrator sessions for forensic analysis. PAM allows access without revealing actual passwords to users.

PIM and PAM tools should be considered for use in an entity’s software development and delivery environment. Naturally, multi-factor authentication (MFA) adds an additional layer of protection, ensuring that stolen credentials alone are insufficient for access.

Entities should also adopt practices such as encrypting secrets, storing them in dedicated secrets management tools, and avoiding hardcoding them into source code. Source-code scanning tools should be applied to scan for exposed secrets at every stage in the development lifecycle. Protect secrets with a vault or secrets manager. Examples solutions include Github Actions Secrets, AWS Secret Manager, and GCP Secret Manager. Do not allow secrets to be stored in the code repository. By implementing the measures described in this section, entities can significantly reduce the risk of credential theft and misuse.

Avoid operating production systems from a development environment

Operating live production systems from development environments introduces significant risks. You should avoid this wherever possible. When access to production systems is necessary, it should be governed by request and approval-based processes that enforce separation of duties. Developers should only be granted temporary access through PAM tools. All actions should be logged and subject to session recording for accountability. By limiting access and enforcing strict controls, entities can reduce the risk of accidental or malicious changes to production systems.

Protect your code and configuration repositories

A common practice of software development teams is for all team members to store software in a code and configuration repository, such as GitHub, GitLab, Bitbucket, and Azure DevOps. The purpose of the repository is to serve as the central location for:

  • software that the team writes
  • software obtained from external sources, that is intended to comprise the entity’s IT solution under development.

The repositories also provide features to automate software artefact management, change and version control, automated testing processes, and many other functions. These features increase development efficiency and reduce complexity. The result is:

  • faster and less expensive software development and delivery costs
  • effective software asset management
  • less errors in software composition
  • decreased risk of a security defect.

Cyber adversaries understand the immense opportunity that unauthorised access to a repository provides. They can steal code and other intellectual property, covertly insert malicious code to compromise systems that rely on the repository, and steal authentication credentials from the repository. This opens the doors to a broad range of malicious activity. Consequently, an entity’s code and configuration repository must be comprehensively protected. This section guides entities on how to protect entities' code and configuration repositories.

Evaluate and monitor entity repositories

The repository chosen serves as the foundation for part, or all, of the entity’s entire codebase including configuration files. Protecting the repository from unauthorised access is clearly important. An entity may choose to host a repository product within its own IT infrastructure. Alternatively, they may utilise a cloud-based repository service. In either case, it is important to evaluate the operational management of the service, including its:

  • underlying infrastructure
  • APIs
  • access control mechanisms
  • support
  • proactive monitoring processes.

Entities should select a reputable provider of code and configuration repositories. Preferably choose one with a long history of effective management. Both Git and Github are well-established but other offerings with similar reputations may be suitable. Regardless of the repository selected, it is important that the software development and delivery teams are trained in how to configure and use the repository to avoid situations resulting in serious security implications.

Software development and delivery that relies on public or open-source repositories introduce unique risks. Public repositories often display contributor profiles. These profiles can be exploited for social engineering attacks like spear-phishing. Ensure you:

  • limit the amount of personal information shared in your profile
  • educate contributors on the importance of protecting their online identities.

With public repositories, an entity’s code may be visible and accessible to anyone. Highly sensitive code, such as fraud detection algorithms and payment gateway access, should always be stored in private repositories to limit external exposure.

Secure the pipeline

Modern software development teams often leverage continuous integration (CI), and continuous delivery and deployment (CD), practices to streamline their software build, test, and release processes. These CI/CD approaches allow small, frequent, code submissions from team members. The submissions can automatically trigger the:

  • software build process
  • continuous testing,
  • automated deployments, to either development, staging, or production environments.

The intent is to achieve an automated software development and delivery process that minimises manual intervention and promotes rapid fully tested production releases.

The security of the CI/CD 'pipeline' is critical to protect the:

  • integrity of the developed code
  • applications and systems that are then built and delivered.

Technical weaknesses in this pipeline can be used by a cyber adversary to steal code, and introduce malicious code, via the:

  • unauthorised modification of the code
  • configuration passing through the pipeline.

This may result in security vulnerabilities being covertly introduced into the delivered product. Consequently, it is important that Queensland Government entities secure their software build and development pipelines. This section contains guidance for securing both the CI/CD platforms. But, it can also be helpful for other means of software development and delivery.

Apply continuous security testing

Security testing is fundamental to ensure that software and systems function as intended while defending against weaknesses and vulnerabilities. This requires a continuous, software lifecycle testing approach that:

  • starts early during development
  • evolves as the software matures.

By integrating security testing into every stage of the software development lifecycle, you can:

  • catch vulnerabilities early
  • reduce risks
  • maintain your entity’s confidence in your solution’s security.

Plan for security defects

Some computer software is designed for use in highly critical environments where there is little or no tolerance for defects. This includes those defects with significant security implications. Some examples would include surgically implanted pacemakers, nuclear powerplant operation, and avionics applications. In these scenarios, an enormous quantity of resources is invested to extensively test the software to attempt to ensure that the software is defect free. However, in typical business applications, the cost to perform the same level of testing is typically considered to be economically infeasible due to perceived lower consequences resulting from a defect. Consequently, it is nearly inevitable that defects, including those with security implications, will exist in an entity’s business applications. They may only be discovered well after deployment.

Acknowledging the inevitability of security defects being identified, even if well after deployment, encourages an entity to adopt an approach intended to track, and remediate, vulnerabilities whenever required. By implementing vulnerability management practices and maintaining a record of design decisions that adversely impact security posture, entities can minimise cyber security risks while maintaining agility and cost efficiency in their software development and delivery. This section describes how an entity can effectively plan for inevitable security defects.

References and further reading

This guidance is structured to generally align with the major topics appearing in the software development and deployment guidance available from the UK National Cyber Security Centre (see Secure development and deployment guidance). However, the guidance has also been updated and augmented using many other sources, including some of the references below. These references provide additional perspectives on how to implement secure software development and delivery within your Queensland Government entity.

Available coding standards