Skip to content
Open
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
8 changes: 8 additions & 0 deletions .devcontainer/post-create.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,12 @@ else
exit 1
fi

# Install project with dev dependencies (pre-commit, mdformat)
echo "[post-create] Installing project dev dependencies..."
pip install -e ".[dev]"

# Install pre-commit git hooks
echo "[post-create] Installing pre-commit hooks..."
pre-commit install
Comment on lines +51 to +56

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

post-create.sh installs uv but then uses plain pip install -e ".[dev]", which bypasses uv.lock and can yield different tool versions than uv run uses. Prefer uv sync --extra dev (and run pre-commit via uv run) so Codespaces uses the locked, reproducible environment.

Suggested change
echo "[post-create] Installing project dev dependencies..."
pip install -e ".[dev]"
# Install pre-commit git hooks
echo "[post-create] Installing pre-commit hooks..."
pre-commit install
echo "[post-create] Installing project dev dependencies via uv..."
"$UV_INSTALL_DIR/uv" sync --extra dev
# Install pre-commit git hooks using uv-managed environment
echo "[post-create] Installing pre-commit hooks..."
"$UV_INSTALL_DIR/uv" run pre-commit install

Copilot uses AI. Check for mistakes.

echo "[post-create] Setup complete."
49 changes: 49 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copilot Instructions — Equinor AppSec

## Project Overview

MkDocs documentation site for Equinor Application Security guidelines. Pure documentation — no application code.

- **Stack:** MkDocs Material theme, Python 3.12+, uv package manager
- **Site URL:** <https://equinor.github.io/appsec/>
- **Repo:** <https://github.com/equinor/appsec/>

## Commands

```bash
uv sync # Install dependencies
uv run mkdocs serve # Local dev server on http://localhost:8000
uv run mkdocs build # Build static site to site/
pip install -e ".[dev]" # Install dev tools (pre-commit, mdformat)
pre-commit install # Set up git hooks
pre-commit run --all-files # Run formatting on all files
Comment on lines +17 to +19

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The command list mixes uv and plain pip. pip install -e ".[dev]" won’t necessarily install into the same environment that uv run ... uses, which can lead to confusion (e.g., pre-commit not found or different mdformat versions). Consider documenting uv sync --extra dev / uv run pre-commit ... instead, to keep everything in the uv-managed environment.

Suggested change
pip install -e ".[dev]" # Install dev tools (pre-commit, mdformat)
pre-commit install # Set up git hooks
pre-commit run --all-files # Run formatting on all files
uv sync --extra dev # Install dev tools (pre-commit, mdformat)
uv run pre-commit install # Set up git hooks
uv run pre-commit run --all-files # Run formatting on all files

Copilot uses AI. Check for mistakes.
```

## Content & Markdown Conventions

- All documentation lives in `docs/`. Do not create files outside this directory for content.
- MkDocs uses **Python-Markdown**, which requires **4-space indentation** for nested lists (not 2-space like GitHub Flavored Markdown).
- `mdformat` with `mdformat-mkdocs` enforces this automatically via pre-commit hooks.
- Use MkDocs Material features: `admonition` blocks, `pymdownx.details` for collapsible sections, `pymdownx.emoji` for icons.
- Navigation structure is managed by `mkdocs-awesome-pages-plugin` — use `.pages` files or directory-level `index.md` for ordering.
- The `git-revision-date-localized` plugin shows last-edit dates, so CI checkouts use `fetch-depth: 0`.
- Theme overrides go in `overrides/` (custom `main.html`).

## Deployments

All three deploy automatically on push to `main`:

1. **GitHub Pages** — `uv run mkdocs gh-deploy --force` ([gh-pages.yml](.github/workflows/gh-pages.yml))
2. **Azure Static Web Apps** — builds `site/`, deploys via Azure token ([azure-static-webapp.yml](.github/workflows/azure-static-webapp.yml))
3. **Backstage TechDocs** — generates and publishes to Azure Blob Storage ([backstage-techdocs.yml](.github/workflows/backstage-techdocs.yml))
Comment on lines +36 to +38

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The relative links to workflow files are incorrect from within .github/ (they currently point to .github/.github/workflows/...). Use paths relative to this file (e.g. workflows/gh-pages.yml) so the links work on GitHub.

Suggested change
1. **GitHub Pages**`uv run mkdocs gh-deploy --force` ([gh-pages.yml](.github/workflows/gh-pages.yml))
2. **Azure Static Web Apps** — builds `site/`, deploys via Azure token ([azure-static-webapp.yml](.github/workflows/azure-static-webapp.yml))
3. **Backstage TechDocs** — generates and publishes to Azure Blob Storage ([backstage-techdocs.yml](.github/workflows/backstage-techdocs.yml))
1. **GitHub Pages**`uv run mkdocs gh-deploy --force` ([gh-pages.yml](workflows/gh-pages.yml))
2. **Azure Static Web Apps** — builds `site/`, deploys via Azure token ([azure-static-webapp.yml](workflows/azure-static-webapp.yml))
3. **Backstage TechDocs** — generates and publishes to Azure Blob Storage ([backstage-techdocs.yml](workflows/backstage-techdocs.yml))

Copilot uses AI. Check for mistakes.

## Dev Container

- Python 3 image with Node.js LTS, port 8000 forwarded
- `post-create.sh` installs uv, dev dependencies, and pre-commit hooks
- `postStartCommand` auto-launches `uv run mkdocs serve`

## Contribution Workflow

Fork → branch → add/edit docs → commit (pre-commit auto-formats) → push → PR to `main`.
See [CONTRIBUTING.md](CONTRIBUTING.md) for full guidelines. Test links, run markdown linter, use a spell checker. Follow conventional commit messages for clarity.

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CONTRIBUTING.md is referenced with a relative link, but from .github/copilot-instructions.md it should go up one level (otherwise it points to .github/CONTRIBUTING.md).

Suggested change
See [CONTRIBUTING.md](CONTRIBUTING.md) for full guidelines. Test links, run markdown linter, use a spell checker. Follow conventional commit messages for clarity.
See [CONTRIBUTING.md](../CONTRIBUTING.md) for full guidelines. Test links, run markdown linter, use a spell checker. Follow conventional commit messages for clarity.

Copilot uses AI. Check for mistakes.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ venv/
.venv/
.dccache
.DS_STORE
.idea/
.idea/
*.egg-info/
3 changes: 3 additions & 0 deletions .mdformat.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# mdformat configuration
# Use 4-space indentation for nested lists (required by MkDocs / Python-Markdown)
[plugin.mkdocs]
8 changes: 8 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
repos:
- repo: https://github.com/executablebooks/mdformat
rev: 0.7.21
hooks:
- id: mdformat
additional_dependencies:
- mdformat-mkdocs

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pre-commit will install mdformat from this repo at rev: 0.7.21, while the project’s dev extra resolves mdformat to a different version in uv.lock. This can cause formatting differences between pre-commit and local mdformat runs. Consider aligning versions and pinning additional_dependencies (e.g. to the same mdformat-mkdocs version used by uv) for deterministic formatting.

Suggested change
- mdformat-mkdocs
- mdformat-mkdocs==0.2.0

Copilot uses AI. Check for mistakes.
files: ^docs/
2 changes: 1 addition & 1 deletion docs/about/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

**Always safe** is one of three pillar in the Equinor strategy. Safety in the digital world includes cyber security. Equinor has many software development teams (internals and partners) and we expect a growth in DevOps teams in the future. Modern software development adopts all aspects of cloud capabilities and thus there is also an increased information security and privacy risk.

>The purpose of the AppSec team is to reduce cyber security risk in Equinor's SDLC - Software Development Life Cycle (DevOps teams).
> The purpose of the AppSec team is to reduce cyber security risk in Equinor's SDLC - Software Development Life Cycle (DevOps teams).

The primary target audience for the team is Equinor's software development community - aka. DevOps teams.

Expand Down
39 changes: 20 additions & 19 deletions docs/experimental/git-signed-commits-old.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
# 🔏 Git Signed Commits: A Guide for Proper Folks Who Ain’t Raised by Wolves 🧐

Now gather ‘round, you young scallywags, and let an old hand set you straight. Back in my day, a man’s word was his bond, and a signature was as good as gold. Nowadays, any two-bit scoundrel with a typewriter hooked up to a lightning machine can go fiddlin’ with your code, impersonatin’ honest folk, and muckin’ things up faster than a hog in a henhouse. 💨
Now gather ‘round, you young scallywags, and let an old hand set you straight. Back in my day, a man’s word was his bond, and a signature was as good as gold. Nowadays, any two-bit scoundrel with a typewriter hooked up to a lightning machine can go fiddlin’ with your code, impersonatin’ honest folk, and muckin’ things up faster than a hog in a henhouse. 💨

**That’s why you gotta sign your Git commits, just like an honest citizen signs a check down at the bank.** 🏦
**That’s why you gotta sign your Git commits, just like an honest citizen signs a check down at the bank.** 🏦

If you don’t, well… don’t come cryin’ when some rascal tampers with your code and the whole shebang crumbles like a biscuit in hot coffee. ☕🍪
If you don’t, well… don’t come cryin’ when some rascal tampers with your code and the whole shebang crumbles like a biscuit in hot coffee. ☕🍪

## 📜 The Rules (And You Better Follow ‘Em, Y’hear?)

✅ **Sign every Git commit you make.** A commit without a signature is like a contract written in invisible ink—ain’t worth a plugged nickel. 💰
✅ **Sign every Git commit you make.** A commit without a signature is like a contract written in invisible ink—ain’t worth a plugged nickel. 💰

✅ **Use SSH keys with a passphrase.** That’s a password, son. And make it a good one. "123456" ain’t a passphrase, it’s an invitation for hooligans.
✅ **Use SSH keys with a passphrase.** That’s a password, son. And make it a good one. "123456" ain’t a passphrase, it’s an invitation for hooligans.

✅ **Keep separate keys for signin’ and loggin’ in.** You wouldn’t use the same key for your house and your barn, would ya?
✅ **Keep separate keys for signin’ and loggin’ in.** You wouldn’t use the same key for your house and your barn, would ya?

✅ **Make sure your branch rules require signed commits.** Otherwise, you might as well leave your front door wide open and hope the raccoons don’t move in.

✅ **GitHub Codespaces might sign commits for ya, but don’t trust it more than your own two hands.** Machines are tricky little devils, and you never know when one’s gonna go haywire. 🤖🔥
✅ **GitHub Codespaces might sign commits for ya, but don’t trust it more than your own two hands.** Machines are tricky little devils, and you never know when one’s gonna go haywire. 🤖🔥

## 🔐 SSH Key Signing (The Best Way for Most Folks)

Expand All @@ -27,6 +27,7 @@ Open up your terminal and generate a dedicated SSH key just for signing your Git
```bash
ssh-keygen -t ed25519 -f ~/.ssh/git_ssh_signing_key_1 -C "Created on <date>, for [your_username] on github.com"
```

Make sure to give it a good passphrase, not something like password123. A weak passphrase is like lockin’ your door with a shoelace.

### 2. 🧠 Add the Key to Your SSH Agent
Expand All @@ -47,7 +48,7 @@ git config --global user.signingkey ~/.ssh/git_ssh_signing_key_1.pub
git config --global commit.gpgsign true
```

Now Git will sign your commits automatically, no fuss, no muss.
Now Git will sign your commits automatically, no fuss, no muss.

## 4. 🔍 Check That Your Commits Are Signed

Expand All @@ -73,20 +74,20 @@ cat ~/.ssh/git_ssh_signing_key_1.pub

To keep your project clean and avoid unwanted shenanigans, enforce signed commits:

1. Go to your **GitHub repository**
2. Navigate to **Settings → Branches**
3. Under **Branch protection rules**, click **Add rule**
4. Select your main branch (usually `main` or `master`)
5. Check **Require signed commits**
1. Go to your **GitHub repository**
1. Navigate to **Settings → Branches**
1. Under **Branch protection rules**, click **Add rule**
1. Select your main branch (usually `main` or `master`)
1. Check **Require signed commits**

Now only signed commits can get through, like a proper gated community. 🚧
Now only signed commits can get through, like a proper gated community. 🚧

## 🎤 Final Words from an Old-Timer Who’s Seen Some Things
## 🎤 Final Words from an Old-Timer Who’s Seen Some Things

Now listen, I ain’t sayin’ you gotta follow these rules. You’re a grown person, you can do what you want. **But if you don’t sign your commits,** don’t come bellyachin’ when some no-good scoundrel impersonates you and sneaks nonsense into your project. 🎭
Now listen, I ain’t sayin’ you gotta follow these rules. You’re a grown person, you can do what you want. **But if you don’t sign your commits,** don’t come bellyachin’ when some no-good scoundrel impersonates you and sneaks nonsense into your project. 🎭

Back in my day, we didn’t have none of this "Git" business. We wrote our code by hand, uphill both ways, in the snow, and we liked it! 📝 **But if we had Git, you better believe we’d sign our work.**
Back in my day, we didn’t have none of this "Git" business. We wrote our code by hand, uphill both ways, in the snow, and we liked it! 📝 **But if we had Git, you better believe we’d sign our work.**

So quit yer lollygaggin’, set up signed commits, and keep your code cleaner than a Sunday suit. 👔
So quit yer lollygaggin’, set up signed commits, and keep your code cleaner than a Sunday suit. 👔

Or don’t. But don’t come cryin’ when your project turns into a three-ring circus. 🎪
Or don’t. But don’t come cryin’ when your project turns into a three-ring circus. 🎪
71 changes: 37 additions & 34 deletions docs/experimental/git-signed-commits-young.md
Original file line number Diff line number Diff line change
@@ -1,74 +1,77 @@
# 🔥 Yo, Code Warriors! 🧑‍💻 Let's Get Sigma with Signed Commits! 🦸‍♂️

Alright, fam, it's time to level up your coding game and flex those sigma vibes. 💪 You know, being that lone wolf 🐺 who's got everything under control without breaking a sweat. Let's dive into why signing your commits is the ultimate sigma move and how to do it. 🚀
Alright, fam, it's time to level up your coding game and flex those sigma vibes. 💪 You know, being that lone wolf 🐺 who's got everything under control without breaking a sweat. Let's dive into why signing your commits is the ultimate sigma move and how to do it. 🚀

---
______________________________________________________________________

## Why Signing Your Commits is Pure Sigma Energy
## Why Signing Your Commits is Pure Sigma Energy

- **🕵️‍♂️ Identity Flex (No Impostors Allowed)**
Signing your commits is like stamping your unique seal of approval. It confirms that *you* made the changes, blocking any wannabe impostors from sneaking in malicious code.
- **🕵️‍♂️ Identity Flex (No Impostors Allowed)**\
Signing your commits is like stamping your unique seal of approval. It confirms that *you* made the changes, blocking any wannabe impostors from sneaking in malicious code.

- **🔒 Code Integrity = Sigma Grindset**
A signed commit ensures your code remains untouched from the moment you commit. If anyone tries to mess with it afterward, the signature breaks, throwing up red flags.
- **🔒 Code Integrity = Sigma Grindset**\
A signed commit ensures your code remains untouched from the moment you commit. If anyone tries to mess with it afterward, the signature breaks, throwing up red flags.

- **🚫🔁 No Replay Shenanigans (Stay Ahead of the Game)**
Signed commits stop attackers from reusing your legit commits in shady contexts, maintaining the flow and context of your code history.
- **🚫🔁 No Replay Shenanigans (Stay Ahead of the Game)**\
Signed commits stop attackers from reusing your legit commits in shady contexts, maintaining the flow and context of your code history.

- **🕵️‍♂️ Audit Like a Boss (Keep It 100)**
With signed commits, tracking changes becomes a breeze, making audits smoother than a fresh jar of Skippy.
- **🕵️‍♂️ Audit Like a Boss (Keep It 100)**\
With signed commits, tracking changes becomes a breeze, making audits smoother than a fresh jar of Skippy.

- **🌟 Boosting Street Cred (Trust & Compliance)**
For projects with strict standards, signed commits show you're playing by the rules, building trust among your crew and users.
- **🌟 Boosting Street Cred (Trust & Compliance)**\
For projects with strict standards, signed commits show you're playing by the rules, building trust among your crew and users.

---
______________________________________________________________________

## How to Sign Your Commits and Embrace the Sigma Lifestyle
## How to Sign Your Commits and Embrace the Sigma Lifestyle

### 🛠️ Step 1: Generate Your SSH Key
Fire up your terminal and punch in:
### 🛠️ Step 1: Generate Your SSH Key

Fire up your terminal and punch in:

```bash
ssh-keygen -t ed25519 -f ~/.ssh/git_ssh_signing_key_1 -C "Created on $(date), for $(whoami) on github.com"
```

This crafts a fresh SSH key for signing.

💡 **Pro tip**: Add a passphrase. Don’t be that person who skips security.
💡 **Pro tip**: Add a passphrase. Don’t be that person who skips security.

### 🛠️ Step 2: Add Your Key to the SSH Agent 🤖
### 🛠️ Step 2: Add Your Key to the SSH Agent 🤖

Alright, so you've got your **fancy new SSH key**, but let's be real—typing your passphrase every time? That's **LAME.** Ain't nobody got time for that.
Alright, so you've got your **fancy new SSH key**, but let's be real—typing your passphrase every time? That's **LAME.** Ain't nobody got time for that.

So let’s make your system remember your key like a **goldfish with a 500 IQ** 🧠🐠:

```bash
ssh-add ~/.ssh/git_ssh_signing_key_1
```

Now your key is locked in 🔐, and you can commit like an absolute **Chad** without re-entering your passphrase every 2 seconds.

Big W. ✅

### 🏴‍☠️ Step 3: Tell Git to Use Your New Key
### 🏴‍☠️ Step 3: Tell Git to Use Your New Key

Yo, **Git ain't psychic**—you gotta tell it to start using that **top-tier** SSH key.
Yo, **Git ain't psychic**—you gotta tell it to start using that **top-tier** SSH key.

Hit it with this:
Hit it with this:

```bash
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/git_ssh_signing_key_1.pub
git config --global commit.gpgsign true
```

This is like **giving Git a treasure map** 🏴‍☠️ so it knows where to find your key.

Now every commit is gonna be signed like a **true security giga-brain.** 🔥

### 🔑 Step 4: Drop That Key into GitHub (Gotta Let the Squad Know)
### 🔑 Step 4: Drop That Key into GitHub (Gotta Let the Squad Know)

Your key is ready, but **GitHub doesn’t know you like that yet.**
Your key is ready, but **GitHub doesn’t know you like that yet.**

So let’s make it official:
So let’s make it official:

```bash
cat ~/.ssh/git_ssh_signing_key_1.pub
Expand All @@ -80,20 +83,20 @@ cat ~/.ssh/git_ssh_signing_key_1.pub

💾 Paste it in and save! **BOOM**. Now GitHub recognizes you like an old friend. 😎

### 🚧 Step 5: Protect Your Branches (Gatekeeping, But in a Good Way)
### 🚧 Step 5: Protect Your Branches (Gatekeeping, But in a Good Way)

Alright, **now we set up branch protection** to make sure NO UNSIGNED COMMITS GET IN. ❌🔓
Alright, **now we set up branch protection** to make sure NO UNSIGNED COMMITS GET IN. ❌🔓

This is like **putting a bouncer** in front of your code, checking IDs before letting commits into the club. 🕶️💪
This is like **putting a bouncer** in front of your code, checking IDs before letting commits into the club. 🕶️💪

Set up **branch protection rules** so **ONLY signed commits** get through.

No signature? 🚫 **Access DENIED.**
No signature? 🚫 **Access DENIED.**

### 🏆 Final Boss Move: Always Sign, Always Secure
### 🏆 Final Boss Move: Always Sign, Always Secure

Using signed commits isn’t just *cool*, it’s **mandatory** if you wanna keep your code safe.
Using signed commits isn’t just *cool*, it’s **mandatory** if you wanna keep your code safe.

Don’t be that dev who gets caught slipping—sign those commits and keep your repo locked down.
Don’t be that dev who gets caught slipping—sign those commits and keep your repo locked down.

💯 **Secure devs are W devs. Now go sign those commits.** 🚀🔥
💯 **Secure devs are W devs. Now go sign those commits.** 🚀🔥
6 changes: 4 additions & 2 deletions docs/security-champion/1-new_security_champion.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ This is where the fun begins.
- 🚀 Explore our [learning platform](./4-learning-platform.md)

!!! question "🎮 Challenge: Hack your way to Merch"
_Hack_ your way to victory and you might just earn some **socks**!

_Hack_ your way to victory and you might just earn some **socks**!\
👉 [Start the game and join the hall of champions](https://forms.microsoft.com/r/cLRPzRtPGQ)

## Add Security Champion events to your calendar 📅
Expand All @@ -29,4 +30,5 @@ You can also find a calendar of events on [SharePoint](https://statoilsrm.sharep
- [#AppSec](https://equinor.slack.com/archives/CMM6FSW5V): Information regarding AppSec

!!! info
Most general information and questions should be posted in [#appsec](https://equinor.slack.com/archives/CMM6FSW5V) so everyone in Equinor has access to it and can participate! Dropping a ```@appsecteam``` in this channel will get our attention immediately.

Most general information and questions should be posted in [#appsec](https://equinor.slack.com/archives/CMM6FSW5V) so everyone in Equinor has access to it and can participate! Dropping a `@appsecteam` in this channel will get our attention immediately.
2 changes: 1 addition & 1 deletion docs/security-champion/2-security_champion_activities.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# Security Champion Activities 🦸‍♀️

## Introduce yourself
Expand All @@ -10,6 +9,7 @@ Say hello in the [Security Champion channel](https://equinor.slack.com/archives/
We have created a few guidelines. Please check them out in our [toolbox](../toolbox/index.md) and consider implementing them in your projects where it makes sense.

!!! info

Feedback is good, so if you have any, feel free to contact us, or even create a PR on our [github repo](https://github.com/equinor/appsec/)!

## Threat Modelling activities
Expand Down
1 change: 1 addition & 0 deletions docs/security-champion/4-learning-platform.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ We have a secure coding learning platform. You as a champion are a perfect match
- Learn things that may help advance your career!

!!! info

You can gain unique merch based on your belt level!

There is a wide arrangement of subjects, and you can do them all if you wish! So there are tracks for:
Expand Down
Loading
Loading