Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
9f7a766
build: add QA tooling and CI quality gates
Msprg Feb 10, 2026
b8cffbb
test: add smoke harness for critical workflows
Msprg Feb 10, 2026
48c06e2
refactor: modernize runtime boundaries and sync/security flows
Msprg Feb 10, 2026
46081ae
feat: add bootstrap5 compatibility layer and page migrations
Msprg Feb 10, 2026
6962bd0
docs: publish modernization plan, checkpoints and runbook
Msprg Feb 10, 2026
5869258
Remediate CodeRabbit findings across docs, security, and runtime guards
Msprg Feb 10, 2026
93e9222
refactor: centralize runtime dependency resolution in Record class
Msprg Feb 10, 2026
d69cb43
docs: add bootstrap 5 gap and library plan
Msprg Apr 1, 2026
5c4c75d
frontend: migrate primary tabs off bootstrap 3 plugin
Msprg Apr 1, 2026
ed45cd0
deps: upgrade phpseclib for composer audit
Msprg Apr 1, 2026
4848202
frontend: migrate help and collapse flows off bootstrap 3 plugin
Msprg Apr 1, 2026
d6957bf
frontend: migrate admin detail tabs off bootstrap 3 plugin
Msprg Apr 1, 2026
be7a47e
frontend: modernize core admin form primitives
Msprg Apr 2, 2026
a7a3ff4
frontend: modernize remaining key and list view primitives
Msprg Apr 2, 2026
ac69a79
frontend: replace bootstrap shell js with local handlers
Msprg Apr 2, 2026
a1c15f9
frontend: remove low-risk jquery helpers
Msprg Apr 2, 2026
5471402
frontend: replace jquery form helpers with native dom
Msprg Apr 2, 2026
d598375
frontend: remove remaining jquery runtime usage
Msprg Apr 2, 2026
aa7d706
frontend: stop loading jquery in base shell
Msprg Apr 2, 2026
cec1e11
frontend: restore native tab and collapse transitions
Msprg Apr 2, 2026
c0dba9e
frontend: prune unused vendored frontend assets
Msprg Apr 2, 2026
fbd5726
frontend: remove bootstrap legacy marker path
Msprg Apr 2, 2026
a028ffa
frontend: replace glyphicon font usage with local svg icons
Msprg Apr 2, 2026
9767ce8
frontend: replace legacy panels with ska cards
Msprg Apr 2, 2026
bc4b41c
frontend: tighten card spacing and icon fallback
Msprg Apr 4, 2026
eae76a2
frontend: fix icon fallback and table row spacing
Msprg Apr 4, 2026
32f5775
frontend: add headless browser capture and restore icons
Msprg Apr 4, 2026
1ba2ff7
frontend: modernize admin settings and inline forms
Msprg Apr 4, 2026
352fb6f
frontend: replace remaining bootstrap 3 check controls
Msprg Apr 4, 2026
173e8a4
frontend: trim remaining bootstrap 3 list helpers
Msprg Apr 4, 2026
b3fe765
docs: refresh bootstrap inventory and smoke guards
Msprg Apr 4, 2026
c3d12f7
frontend: replace remaining bootstrap helper classes
Msprg Apr 4, 2026
5e65288
frontend: replace legacy glyphicons on core pages
Msprg Apr 4, 2026
ef7c9ee
frontend: drop dead glyphicon css aliases
Msprg Apr 4, 2026
29375c1
frontend: remove legacy hidden helper usage
Msprg Apr 4, 2026
7d20c9b
frontend: prune unused bootstrap compat utilities
Msprg Apr 4, 2026
1cd8fd7
frontend: replace bootstrap shell nav classes
Msprg Apr 4, 2026
63a6e05
frontend: replace bootstrap tab css with local styles
Msprg Apr 4, 2026
987af47
frontend: replace bootstrap table classes on core pages
Msprg Apr 4, 2026
63ea57c
frontend: localize button and alert styling
Msprg Apr 4, 2026
8f05665
frontend: retire bootstrap compat stylesheet
Msprg Apr 4, 2026
1994c87
frontend: localize bootstrap grid and text utilities
Msprg Apr 4, 2026
53a49b7
frontend: localize shared form control styling
Msprg Apr 4, 2026
5ab27f0
frontend: retire legacy shell and form helper classes
Msprg Apr 4, 2026
2639e1b
frontend: remove bootstrap css from runtime
Msprg Apr 4, 2026
8c9b8c2
frontend: prune retired bootstrap vendor assets
Msprg Apr 4, 2026
1375f52
frontend: retire bootstrap in-state classes
Msprg Apr 4, 2026
57b1c11
frontend: clean up secondary utility pages
Msprg Apr 5, 2026
5748425
frontend: add ska aliases for bootstrap handoff prep
Msprg Apr 5, 2026
78f3d8e
frontend: hand off input groups and check controls
Msprg Apr 5, 2026
f6b5ed7
smoke: add authenticated browser interaction checks
Msprg Apr 5, 2026
1f252ac
frontend: hand off shared form controls
Msprg Apr 5, 2026
27684f7
frontend: hand off shared button classes
Msprg Apr 5, 2026
839befa
frontend: hand off shared alert classes
Msprg Apr 5, 2026
b53396d
frontend: hand off shared layout utility classes
Msprg Apr 5, 2026
cd62598
frontend: clean runtime helper class stragglers
Msprg Apr 5, 2026
23fe5c1
frontend: prune retired bootstrap css aliases
Msprg Apr 5, 2026
b130d3d
frontend: add bootstrap 5 css baseline
Msprg Apr 5, 2026
37ad80c
frontend: hand off secondary pages to bootstrap 5 css
Msprg Apr 5, 2026
949c545
frontend: migrate help content to bootstrap 5 components
Msprg Apr 5, 2026
64780c0
frontend: migrate public key detail pages to bootstrap 5
Msprg Apr 5, 2026
52d2014
frontend: migrate public key admin page to bootstrap 5
Msprg Apr 5, 2026
9fb13a5
frontend: migrate groups list page to bootstrap 5
Msprg Apr 5, 2026
e2b3964
frontend: migrate servers list page to bootstrap 5
Msprg Apr 5, 2026
05bbc9b
frontend: migrate group detail page to bootstrap 5
Msprg Apr 5, 2026
d064aeb
frontend: migrate server detail page to bootstrap 5
Msprg Apr 5, 2026
8fd41a6
frontend: migrate server account page to bootstrap 5
Msprg Apr 5, 2026
6324481
frontend: hand off list page layout to bootstrap 5
Msprg Apr 5, 2026
1165d78
frontend: hand off group detail layout to bootstrap 5
Msprg Apr 5, 2026
3173e6b
frontend: hand off server detail layout to bootstrap 5
Msprg Apr 5, 2026
07b6037
frontend: complete bootstrap 5 ownership handoff
Msprg Apr 6, 2026
db36110
Merge branch 'master' into bootstrap5-upgrade-part1
Msprg Apr 6, 2026
6c6abb1
Update templates/user.php
Msprg Apr 6, 2026
b9c0ff8
Update templates/functions.php
Msprg Apr 6, 2026
ce2ab65
Update templates/base.php
Msprg Apr 6, 2026
09cca93
fix: apply CodeRabbit auto-fixes
coderabbitai[bot] Apr 6, 2026
b59ddb0
Update docs/phase-7-checkpoint.md
Msprg Apr 6, 2026
3295ad5
fix: apply CodeRabbit auto-fixes
coderabbitai[bot] Apr 6, 2026
d0b5007
fix: apply CodeRabbit auto-fixes
coderabbitai[bot] Apr 6, 2026
aa31df6
security: harden login input guards
Msprg Apr 6, 2026
f620e9f
fix: batch of fixes
Msprg Apr 6, 2026
df1c065
model: harden user runtime dependency guards
Msprg Apr 6, 2026
688d5b4
views: harden group and key error handling
Msprg Apr 6, 2026
e87f108
services: harden request and smoke runtime guards
Msprg Apr 7, 2026
ec4a53b
services: harden auth, routing, and group workflows
Msprg Apr 7, 2026
1d799d9
runtime: harden sync and key metadata handling
Msprg Apr 7, 2026
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
38 changes: 38 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,45 @@ on:
types: [ published ]

jobs:
quality-gates:
runs-on: ubuntu-22.04
steps:
- name: Check out repository
uses: actions/checkout@v6

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: ldap, mbstring, mysqli, pcntl, ssh2
coverage: none

- name: Install dependencies
run: composer install --no-interaction --prefer-dist

- name: Composer validate
run: composer validate --strict

- name: Composer audit
run: composer audit

- name: Composer platform requirements
run: composer check-platform-reqs

- name: Docker compose config validation
run: docker compose config -q
Comment thread
Msprg marked this conversation as resolved.

- name: PHP lint
run: composer run lint

- name: PHP static analysis
run: composer run stan

- name: Smoke harness dry-run
run: composer run smoke:dry-run

build-matrix:
needs: quality-gates
if: github.event_name != 'pull_request'
outputs:
safe_ref: ${{ steps.ref.outputs.safe_ref }}
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ extensions/*.php
docker-compose*
docker/
/vendor/
var/
scripts/smoke/fixtures/sync/*.txt
testenvs.env
17 changes: 17 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

$finder = PhpCsFixer\Finder::create()
->in([
__DIR__ . '/model',
__DIR__ . '/scripts',
__DIR__ . '/services',
])
->name('*.php');

return (new PhpCsFixer\Config())
->setRiskyAllowed(false)
->setRules([
'@PSR12' => true,
'line_ending' => true,
])
->setFinder($finder);
110 changes: 78 additions & 32 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

This document gives AI agents enough context to work safely in this repo.

## Current status (Phase 10 complete)
- Modernization phases 0-10 are implemented on the Bootstrap 5 modernization branch (`bootstrap5-upgrade*` lineage).
- Runtime state container is in use (`services/runtime_state.php`) with compatibility fallback paths still present.
- Request/auth/CSRF/security-header flow is service-based in `requesthandler.php`.
- Bootstrap, jQuery, and the Bootstrap 5 compatibility runtime are no longer loaded in the browser.
- Frontend shell/layout behavior is now repo-local in `public_html/style.css` and `public_html/extra.js`.
- Smoke harness and quality gates are available and expected in agent workflow.

## What this project is
- SKA is a PHP web app that centralizes SSH public key management.
- It integrates with LDAP/AD for users and groups.
Expand All @@ -15,29 +23,42 @@ This document gives AI agents enough context to work safely in this repo.
- Views/controllers: `views/`
- Templates: `templates/`
- Models: `model/`
- Services: `services/` (auth, init scripts)
- Services: `services/`
- CLI scripts: `scripts/` (sync + cron jobs)
- Documentation: `docs/`

## Configuration and secrets
- Main config template: `config/config.ini.example`
- Real config: `config/config.ini` (not in repo)
- Sync SSH keys expected at:
- `config/keys-sync` (private key)
- `config/keys-sync.pub` (public key)
- Do not commit any real secrets or keys.
- Never commit real secrets, keys, or production credentials.

## Critical compatibility contract
Do not break these unless explicitly approved and documented:
- LDAP login/auth flow.
- Public key add/remove lifecycle.
- Access rule add/remove lifecycle.
- Sync behavior and output compatibility.
- Audit/event logging semantics.
- Sync key paths:
- `config/keys-sync`
- `config/keys-sync.pub`

Reference: `docs/compatibility-contract.md`

## Core workflows (high level)
- Login: LDAP auth via `services/auth.php` and `ldap.php`, session in `requesthandler.php`.
- Key upload: stored in `model/publickey.php` and related directories.
- Access rules: `model/access.php` and related access option classes.
- Key distribution: `scripts/sync.php` over SSH to write files under `/var/local/keys-sync/`.
- Periodic tasks:
- `scripts/ldap_update.php` (LDAP sync)
- `scripts/supervise_external_keys.php` (detect external keys)
- `scripts/syncd.php` (daemon for key sync)
- Login/auth: `services/auth.php`, `services/login_flow.php`, `ldap.php`
- Request policy/auth/csrf: `services/request_policy_guard.php`, `services/request_auth_guard.php`, `services/request_csrf_guard.php`
- Key lifecycle: `services/key_lifecycle_service.php`, `model/publickey.php`
- Access lifecycle: `services/access_rule_service.php`, `model/access.php`, `model/accessoption.php`
- Sync distribution: `scripts/sync.php`, `scripts/sync-common.php`, `scripts/syncd.php`
- External key supervision: `scripts/supervise_external_keys.php`
- LDAP sync: `scripts/ldap_update.php`

## Data model (key tables)
See `migrations/00x.php` for schema.
See migrations (`migrations/00x.php`) for schema details.
- Users: `user`, `entity`
- Groups: `group`, `group_member`
- Servers: `server`, `server_account`
Expand All @@ -46,29 +67,54 @@ See `migrations/00x.php` for schema.
- Events/audit: `entity_event`, `server_event`
- Sync: `sync_request`, `external_key`

## Development and runtime notes
- PHP 8.2+, MySQL/MariaDB, LDAP.
- Docker is the preferred deployment method (`Dockerfile`, `docker-compose.yml`).
- Cron and supervisor configs live under `etc/`.
- Web assets in `public_html/` (Bootstrap + jQuery).
## Validation workflow for agents
Run these before handoff:

```bash
source testenvs.env
make ci-check
make smoke-dry-run
make smoke
```

Security note:
- Do not use `COMPOSER_ALLOW_SUPERUSER=1` for local/dev workflows.
- If a CI runner must execute Composer as root, follow the guidance in [docs/operations-runbook.md](/var/www/ska/docs/operations-runbook.md) and keep that exception scoped to the CI environment.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use a repo-relative link for the runbook.

/var/www/ska/docs/operations-runbook.md is a local filesystem path, so the link is broken in GitHub and most editors. Point this at docs/operations-runbook.md instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@AGENTS.md` at line 82, The link in AGENTS.md currently points to an absolute
filesystem path (/var/www/ska/docs/operations-runbook.md) which is broken in
GitHub and editors; update the Markdown link text to use a repo-relative path
(docs/operations-runbook.md) so the link resolves correctly in the repository
and editors, leaving the surrounding sentence unchanged.


If `testenvs.env` is not present in the environment, coordinate with the user for smoke variables.

## Smoke workflow expectations
Smoke harness validates:
- login page + LDAP auth
- key add/remove for authenticated user
- access rule add/remove for target account
- sync preview output against fixture

References:
- `docs/smoke-tests.md`
- `docs/operations-runbook.md`

## Where to look for changes
- UI changes: `templates/` and `views/`
- Access logic: `model/access.php` and `model/accessoption.php`
- LDAP behavior: `ldap.php` and `services/auth.php`
- Sync behavior: `scripts/sync.php` and `scripts/sync-common.php`
- UI and UX: `templates/`, `views/`, compatibility assets in `public_html/`
- Access logic: `model/access.php`, `model/accessoption.php`, `services/access_rule_service.php`
- LDAP behavior: `ldap.php`, `services/auth.php`
- Sync behavior: `scripts/sync.php`, `scripts/sync-common.php`, `scripts/syncd.php`
- Request/auth/security headers: `requesthandler.php`, `services/request_*`, `services/response_security_headers.php`

## Safety checks for edits
- Validate any change that touches SSH key generation or distribution.
- Do not change key file paths without updating docs and server config.
- Avoid modifying LDAP queries without checking group/user assumptions.
- Keep audit/event logging intact when altering access flows.

## Testing guidance
- No automated tests in repo.
- For changes, prefer targeted manual verification:
- Login and LDAP auth flow
- Add/Remove public keys
- Create/Remove access rules
- Trigger a sync (CLI) and verify output files
- Validate any change touching SSH sync, key generation, or host verification paths.
- Avoid changing LDAP query behavior unless assumptions and migration notes are explicit.
- Keep audit/event logging intact when changing key/access/admin flows.
- Keep schema-compatible migrations unless a breaking change is explicitly approved.

## Modernization docs map
- Plan: `docs/modernization-plan.md`
- Risks: `docs/modernization-risks.md`
- Roadmap: `docs/modernization-roadmap.md`
- Checkpoints:
- `docs/phase-5-checkpoint.md`
- `docs/phase-6-checkpoint.md`
- `docs/phase-7-checkpoint.md`
- `docs/phase-8-checkpoint.md`
- `docs/phase-9-checkpoint.md`
- `docs/phase-10-checkpoint.md`
45 changes: 45 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.PHONY: lint stan qa format format-check composer-validate composer-audit platform-check docker-config-check ci-check smoke smoke-dry-run smoke-web smoke-sync smoke-sync-record

lint:
composer run lint

stan:
composer run stan

qa:
composer run qa

format:
composer run format

format-check:
composer run format:check

composer-validate:
composer validate --strict

composer-audit:
composer audit

platform-check:
composer check-platform-reqs

docker-config-check:
docker compose config -q

ci-check: composer-validate composer-audit platform-check docker-config-check qa

smoke:
bash scripts/smoke/run.sh

smoke-dry-run:
bash scripts/smoke/run.sh --dry-run

smoke-web:
bash scripts/smoke/run.sh --web-only

smoke-sync:
bash scripts/smoke/run.sh --sync-only

smoke-sync-record:
bash scripts/smoke/run.sh --sync-only --record-sync
45 changes: 44 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Installation
CREATE DATABASE `ska-db` DEFAULT CHARACTER SET utf8mb4;
GRANT ALL ON `ska-db`.* to 'ska-user'@'localhost';

5. Copy the file `config/config-sample.ini` to `config/config.ini` and edit the settings as required.
5. Copy the file `config/config.ini.example` to `config/config.ini` and edit the settings as required.

6. Set up authnz_ldap for your virtual host (or any other authentication module that will pass on an Auth-user
variable to the application).
Expand Down Expand Up @@ -108,6 +108,49 @@ Usage

Anyone in the LDAP group defined under `admin_group_cn` in `config/config.ini` will be able to manage accounts and servers.

Development checks
------------------

Install development dependencies:

composer install

Run quality checks:

make ci-check

Run smoke harness dry-run:

make smoke-dry-run

Run smoke workflows (requires environment variables, see docs):

make smoke

Run individual checks:

make lint
make stan
make composer-validate
make composer-audit
make platform-check
make docker-config-check

Inspect sync runtime timeout diagnostics:

php scripts/sync.php --diagnostics

Smoke test documentation: `docs/smoke-tests.md`
Operations runbook: `docs/operations-runbook.md`
Modernization checkpoints and roadmap:
- `docs/modernization-roadmap.md`
- `docs/phase-5-checkpoint.md`
- `docs/phase-6-checkpoint.md`
- `docs/phase-7-checkpoint.md`
- `docs/phase-8-checkpoint.md`
- `docs/phase-9-checkpoint.md`
- `docs/phase-10-checkpoint.md`

Key distribution
----------------

Expand Down
16 changes: 16 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,21 @@
"ext-ssh2": "*",
"phpseclib/phpseclib": "^3.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.90",
"php-parallel-lint/php-parallel-lint": "^1.4",
"phpstan/phpstan": "^1.12"
},
"scripts": {
"lint": "parallel-lint --exclude vendor --exclude .git --exclude docs .",
"stan": "phpstan analyse --configuration=phpstan.neon.dist --memory-limit=1G",
"format": "php-cs-fixer fix --config=.php-cs-fixer.dist.php",
"format:check": "php-cs-fixer fix --config=.php-cs-fixer.dist.php --dry-run --diff",
"smoke:dry-run": "bash scripts/smoke/run.sh --dry-run",
"qa": [
"@lint",
"@stan"
]
},
"license": "Apache-2.0"
}
Loading
Loading