Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@
- Follow clean code principles
- Write comprehensive tests
- Use meaningful variable names
- Use British English spelling

## Project-Specific instructions
Check the following files for any project-specific coding standards or guidelines:
- .github/instructions/project/instructions.md
- If no project-specific conventions are defined there, use the general and language-specific best practices referenced below.
- Language-specific instructions may also be found in the language-specific instruction files listed below. Always check those for any additional guidelines or standards that may apply to your codebase.

## Language-Specific Instructions
Always follow security best practices as outlined in:
- .github/instructions/general/SECURITY.md
- .github/instructions/general/security.instructions.md
Follow additional language-specific guidelines in:
- .github/instructions/language-specific/INSTRUCTIONS-CDK.md
- .github/instructions/language-specific/INSTRUCTIONS-CLOUDFORMATION.md
- .github/instructions/language-specific/INSTRUCTIONS-JAVA.md
- .github/instructions/language-specific/INSTRUCTIONS-KOTLIN.md
- .github/instructions/language-specific/INSTRUCTIONS-PYTHON.md
- .github/instructions/language-specific/INSTRUCTIONS-TERRAFORM.md
- .github/instructions/language-specific/INSTRUCTIONS-SAM.md
- .github/instructions/language-specific/INSTRUCTIONS-TYPESCRIPT.md

## Project-Specific Rules
- .github/instructions/languages/cdk.instructions.md
- .github/instructions/languages/cloudformation.instructions.md
- .github/instructions/languages/python.instructions.md
- .github/instructions/languages/terraform.instructions.md
- .github/instructions/languages/sam.instructions.md
- .github/instructions/languages/typescript.instructions.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
---
applyTo: '*'
applyTo: '**/*'
description: "Comprehensive secure coding instructions for all languages and frameworks, based on OWASP Top 10 and industry best practices."
---

This file is mastered in https://github.com/NHSDigital/eps-copilot-instructions and is automatically synced to all EPS repositories. To suggest changes, please open an issue or pull request in the eps-copilot-instructions repository.

# Secure Coding and OWASP Guidelines

## Instructions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ description: 'Guidelines for writing, reviewing, and maintaining AWS CDK (TypeSc
applyTo: 'packages/cdk/**/*.ts'
---

This file is mastered in https://github.com/NHSDigital/eps-copilot-instructions and is automatically synced to all EPS repositories. To suggest changes, please open an issue or pull request in the eps-copilot-instructions repository.

# AWS CDK TypeScript Development

This file provides instructions for generating, reviewing, and maintaining AWS CDK code in the `packages/cdk` folder. It covers best practices, code standards, architecture, and validation for infrastructure-as-code using AWS CDK in TypeScript.
Expand Down Expand Up @@ -90,7 +92,7 @@ export class CptsApiAppStack extends Stack {
## Validation and Verification

- Build: `make cdk-synth`
- Lint: `npm run lint --workspace packges/cdk`
- Lint: `npm run lint --workspace packages/cdk`

## Maintenance

Expand Down
110 changes: 110 additions & 0 deletions .github/instructions/languages/cloudformation.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
description: 'Guidelines for writing, reviewing, and maintaining cloudformation templates'
applyTo: 'cloudformation/**'
---

This file is mastered in https://github.com/NHSDigital/eps-copilot-instructions and is automatically synced to all EPS repositories. To suggest changes, please open an issue or pull request in the eps-copilot-instructions repository.

## General
- Prefer YAML (not JSON). Follow existing style in [cloudformation/account_resources.yml](cloudformation/account_resources.yml), [cloudformation/ci_resources.yml](cloudformation/ci_resources.yml), [cloudformation/artillery_resources.yml](cloudformation/artillery_resources.yml), [cloudformation/account_resources_bootstrap.yml](cloudformation/account_resources_bootstrap.yml), [cloudformation/management.yml](cloudformation/management.yml).
- Always start with `AWSTemplateFormatVersion: "2010-09-09"`.
- Keep descriptions concise (> operator used only for multi‑line).
- Use logical region `eu-west-2` unless cross‑region behavior explicitly required.
- Maintain tagging pattern: version, stack, repo, cfnDriftDetectionGroup (see deployment scripts in [.github/scripts/release_code.sh](.github/scripts/release_code.sh) and [.github/scripts/create_changeset_existing_tags.sh](.github/scripts/create_changeset_existing_tags.sh)).

## Parameters
- Reuse and align parameter naming with existing templates: `LogRetentionDays`, `Env`, `SplunkHECEndpoint`, `DeployDriftDetection`.
- For numeric retention days replicate allowed values list from [SAMtemplates/lambda_resources.yaml](SAMtemplates/lambda_resources.yaml) or [cloudformation/account_resources.yml](cloudformation/account_resources.yml).
- Use `CommaDelimitedList` for OIDC subject claim filters like in [cloudformation/ci_resources.yml](cloudformation/ci_resources.yml).

## Conditions
- Follow pattern `ShouldDeployDriftDetection` (see [SAMtemplates/lambda_resources.yaml](SAMtemplates/lambda_resources.yaml)); avoid ad‑hoc condition names.
- If creating a never-used placeholder stack use pattern from [cloudformation/empty_stack.yml](cloudformation/empty_stack.yml).

## IAM Policies
- Split large CloudFormation execution permissions across multiple managed policies (A, B, C, D) to keep each rendered size < 6144 chars (see check logic in [scripts/check_policy_length.py](scripts/check_policy_length.py)).
- Scope resources minimally; prefer specific ARNs (e.g. logs, KMS aliases) as in [cloudformation/account_resources.yml](cloudformation/account_resources.yml).
- When granting CloudFormation execution access: separate IAM‑focused policy (`GrantCloudFormationExecutionAccessIAMPolicy`) from broad service policies.
- Use exports for policy ARNs with naming `ci-resources:GrantCloudFormationExecutionAccessPolicyA` pattern.

## KMS
- Alias naming: `alias/CloudwatchLogsKmsKeyAlias`, `alias/SecretsKMSKeyAlias`, `alias/ArtifactsBucketKMSKeyAlias` (see [cloudformation/account_resources.yml](cloudformation/account_resources.yml), [cloudformation/account_resources_bootstrap.yml](cloudformation/account_resources_bootstrap.yml)).
- Grant encrypt/decrypt explicitly for principals (e.g. API Gateway, Lambda) mirroring key policy blocks in [cloudformation/account_resources.yml](cloudformation/account_resources.yml).

## Secrets / Parameters
- SecretsManager resources must depend on alias if needed (`DependsOn: SecretsKMSKeyKMSKeyAlias`) like in [cloudformation/account_resources_bootstrap.yml](cloudformation/account_resources_bootstrap.yml).
- Export secret IDs (not ARNs unless specifically required) using colon-separated naming with stack name (pattern in outputs section of account templates).
- Default placeholder value `ChangeMe` for bootstrap secrets.

## S3 Buckets
- Apply `PublicAccessBlockConfiguration` and encryption blocks consistent with [cloudformation/account_resources.yml](cloudformation/account_resources.yml).
- Suppress guard rules using `Metadata.guard.SuppressedRules` where legacy exceptions exist (e.g. replication / logging) matching existing patterns.

## Lambda / SAM
- Shared lambda resources belong in SAM template ([SAMtemplates/lambda_resources.yaml](SAMtemplates/lambda_resources.yaml)); CloudFormation templates should not duplicate build-specific metadata.
- Suppress cfn-guard rules where justified via `Metadata.guard.SuppressedRules` (e.g. `LAMBDA_INSIDE_VPC`, `LAMBDA_CONCURRENCY_CHECK`) only if precedent exists.

## Exports & Cross Stack
- Output export naming pattern: `!Join [":", [!Ref "AWS::StackName", "ResourceLogicalName"]]`.
- Reference exports via `!ImportValue stack-name:ExportName` (see Proxygen role usage in [SAMtemplates/lambda_resources.yaml](SAMtemplates/lambda_resources.yaml)).
- Avoid changing existing export names (breaking downstream stacks and scripts).

## OIDC / Roles
- Federated trust for GitHub actions must use conditions:
- `token.actions.githubusercontent.com:aud: sts.amazonaws.com`
- `ForAnyValue:StringLike token.actions.githubusercontent.com:sub: <ClaimFilters>`
(pattern in roles inside [cloudformation/ci_resources.yml](cloudformation/ci_resources.yml)).
- When adding a new OIDC role add matching parameter `<RoleName>ClaimFilters` and outputs `<RoleName>` and `<RoleName>Name`.

## Drift Detection
- Tag stacks with `cfnDriftDetectionGroup` (deployment scripts handle this). Config rules should filter on `TagKey: cfnDriftDetectionGroup` and specific `TagValue` (patterns in [SAMtemplates/lambda_resources.yaml](SAMtemplates/lambda_resources.yaml)).
- Avoid duplicating rule identifiers; follow `${AWS::StackName}-CloudFormationDriftDetector-<Group>`.

## Route53
- Environment hosted zones template ([cloudformation/eps_environment_route53.yml](cloudformation/eps_environment_route53.yml)) uses parameter `environment`; management template updates NS records referencing environment zones.

## Style / Lint / Guard
- Keep resources grouped with `#region` / `#endregion` comments as in existing templates for readability.
- Use `Metadata.cfn-lint.config.ignore_checks` only when upstream spec mismatch (example: W3037 in large policy templates).
- Ensure new templates pass `make lint-cloudformation` and `make cfn-guard` (scripts: [scripts/run_cfn_guard.sh](scripts/run_cfn_guard.sh)).

## Naming Conventions
- Logical IDs: PascalCase (`ArtifactsBucketKMSKey`, `CloudFormationDeployRole`).
- Managed policy logical IDs end with `Policy` or `ManagedPolicy`.
- KMS Key alias logical IDs end with `Alias` (e.g. `CloudwatchLogsKmsKeyAlias`).
- Secrets logical IDs end with `Secret`.

## Security
- Block public access for all buckets unless explicitly required.
- Encrypt logs with KMS key; provide alias export (see `CloudwatchLogsKmsKeyAlias`).
- Limit wildcard `Resource: "*"` where service requires (e.g. some IAM, CloudFormation actions). Prefer service/resource ARNs otherwise.

## When Adding New Resource Types
- Update execution policies in [cloudformation/ci_resources.yml](cloudformation/ci_resources.yml) minimally; do not expand existing broad statements unnecessarily.
- Run policy length check (`make test` invokes [scripts/check_policy_length.py](scripts/check_policy_length.py)) after modifications.

## Do Not
- Do not hardcode account IDs; use `${AWS::AccountId}`.
- Do not remove existing exports or rename keys.
- Do not inline large policy statements in a single managed policy if size risk exists.

## Examples
- IAM Role with OIDC trust: replicate structure from `CloudFormationDeployRole` in [cloudformation/ci_resources.yml](cloudformation/ci_resources.yml).
- KMS key + alias + usage policy: follow `ArtifactsBucketKMSKey` block in [cloudformation/account_resources.yml](cloudformation/account_resources.yml).

## Testing
- After changes: run `make lint-cloudformation` and `make cfn-guard`.
- For SAM-related cross-stack exports ensure `sam build` (see [Makefile](Makefile)) passes.

## Automation Awareness
- Deployment scripts expect unchanged parameter names & export patterns (see [.github/scripts/execute_changeset.sh](.github/scripts/execute_changeset.sh), [.github/scripts/release_code.sh](.github/scripts/release_code.sh)).
- Changes to tagging keys must be reflected in release / changeset scripts; avoid unless necessary.

## Preferred Patterns Summary
- Exports: colon join
- Tags: version, stack, repo, cfnDriftDetectionGroup
- Conditions: prefixed with `Should`
- Claim filter parameters: `<RoleName>ClaimFilters`
- Secrets: depend on KMS alias, default `ChangeMe`

Use these rules to guide completions for any new or modified CloudFormation template in this repository.
93 changes: 93 additions & 0 deletions .github/instructions/languages/python.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
description: 'Guidelines for writing high-quality, maintainable python code with best practices for logging, error handling, code organization, naming, formatting, and style.'
applyTo: '**/*.py'
---

This file is mastered in https://github.com/NHSDigital/eps-copilot-instructions and is automatically synced to all EPS repositories. To suggest changes, please open an issue or pull request in the eps-copilot-instructions repository.

# Python Copilot Instructions

These instructions are designed to guide GitHub Copilot in generating effective, maintainable, and domain-appropriate Python code. They are intended to be generic and applicable to a wide range of Python projects.

## 1. Code Organization & Structure
- Organize code into logical modules and packages. Use directories such as `core/`, `services/`, `utils/` for separation of concerns.
- Place entry points (e.g., `handler.py`) at the top level of the main package.
- Use `__init__.py` files to define package boundaries and expose public APIs.
- Group related functions and classes together. Avoid large monolithic files.
- Store tests in a dedicated `tests/` directory, mirroring the structure of the main codebase.

## 2. Naming Conventions
- Use `snake_case` for function and variable names.
- Use `PascalCase` for class names.
- Prefix private functions and variables with a single underscore (`_`).
- Name modules and packages using short, descriptive, lowercase names.
- Use clear, descriptive names for all symbols. Avoid abbreviations unless they are widely understood.

## 3. Formatting & Style
- Follow [PEP 8](https://peps.python.org/pep-0008/) for code style and formatting.
- Use 4 spaces per indentation level. Do not use tabs.
- Limit lines to 120 characters.
- Use blank lines to separate functions, classes, and logical sections.
- Place imports at the top of each file, grouped by standard library, third-party, and local imports.
- Use single quotes for strings unless double quotes are required.
- Add docstrings to all public modules, classes, and functions. Use triple double quotes for docstrings.

## 4. Logging Best Practices
- Use the standard `logging` library for all logging.
- Configure logging in the main entry point or via a dedicated utility module.
- Use appropriate log levels: `debug`, `info`, `warning`, `error`, `critical`.
- Avoid logging sensitive information.
- Include contextual information in log messages (e.g., function names, parameters, error details).
- Example:
```python
import logging
logger = logging.getLogger(__name__)
logger.info('Processing event: %s', event)
```

## 5. Error Handling Best Practices
- Use `try`/`except` blocks to handle exceptions gracefully.
- Catch specific exceptions rather than using bare `except`.
- Log exceptions with stack traces using `logger.exception()`.
- Raise custom exceptions for domain-specific errors.
- Validate inputs and fail fast with clear error messages.
- Example:
```python
try:
result = process_event(event)
except ValueError as e:
logger.error('Invalid event: %s', e)
raise
```

## 6. Testing Guidelines
- Write unit tests for all public functions and classes.
- Use `pytest` as the preferred testing framework.
- Name test files and functions using `test_` prefix.
- Use fixtures for setup and teardown.
- Mock external dependencies in tests.
- Ensure tests are isolated and repeatable.

## 7. Dependency Management
- Use `pyproject.toml` to specify dependencies.
- Never use `requirements.txt` to specify dependencies.
- Pin versions for critical dependencies.
- Avoid unnecessary dependencies.

## 8. Documentation
- Document all public APIs with clear docstrings.
- Use [Google](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) or [NumPy](https://numpydoc.readthedocs.io/en/latest/format.html) style for docstrings.
- Provide usage examples in README files.

## 9. Security & Privacy
- Do not log or expose secrets, credentials, or sensitive data.
- Validate and sanitize all external inputs.
- Use environment variables for configuration secrets.

## 10. General Guidelines
- Prefer readability and simplicity over cleverness.
- Refactor duplicated code into reusable functions or classes.
- Use type hints for function signatures and variables where appropriate.
- Avoid global variables; use function arguments or class attributes.

---
Loading
Loading