Skip to content

feat(admin-api): a versioned admin API under /api/v1/admin (stacked on #962) - #966

Open
rubenvdlinde wants to merge 6 commits into
developmentfrom
feat/admin-public-api
Open

rubenvdlinde wants to merge 6 commits into
developmentfrom
feat/admin-public-api

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Builds admin-public-api (#772): a documented, versioned admin API under /api/v1/admin.

Stacked on #962 (admin-scoped-roles). Every endpoint is guarded by one of its area classes, so merge #962 first. The diff here is the last four commits.

What changed

21 v1 operations, each guarded in Nextcloud's middleware by one admin area:

Area Endpoints
any area GET /api/v1/admin: the index with apiVersion 1, versions, your areas and every path
Policies GET, PUT /policies (the Policies area settings from #962)
People and offboarding GET /suites (metadata only, paged), POST /offboarding
Applications and machine access GET, POST /applications; GET, DELETE /applications/{id}; POST .../approve, .../reject; GET, PUT .../lease-policy
Audit and compliance GET /audit; GET, POST /compliance/reports; GET /compliance/reports/{id}; GET, POST /siem/sinks; PUT, DELETE /siem/sinks/{id}

The controllers (AdminIndexController, AdminPeopleController, AdminApplicationController, AdminAuditController) only map parameters. They call the services the admin screens call. Every write has a #[UserRateLimit].

Registering an application, reading one (with its public certificate) and its lease policy were added for the Terraform provider (#779).

Left out

Contract

  • docs/api/admin-v1.openapi.json (OpenAPI 3.1) describes every route. @redocly/cli lint reports it valid with no warnings, and the new workflow admin-api.yml runs that lint in CI.
  • AdminApiContractTest fails when the document, the route table or the index path list disagree. It also checks that each route has exactly one area guard, matching the area the index names. No route is public, needs a fresh password, or reaches forceRevoke or reinstate. An Audit-only account reaches the audit routes and nothing else.
  • tests/integration/admin-api.postman_collection.json seeds an Audit-only service account through Nextcloud's provisioning API and authorizedgroups/saveSettings. It checks the account reaches audit, compliance and SIEM, and is refused policies, suites, applications and offboarding. It checks suites and sinks carry no key material or secret, then removes the account. run-newman.sh runs it.
  • A docs page, docs/tutorials/admin/02-admin-api.md, covers service account setup, app passwords and the versioning rule.

Tests

Each controller has PHPUnit tests through the controller: AdminIndexControllerTest, AdminPeopleControllerTest, AdminApplicationControllerTest and AdminAuditControllerTest. They cover the suite list without privateKey/certificate, offboarding through the screen's service, approval recording the caller, 404s, lease policy read and write, and sinks without their HMAC secret or credential. All of these fail on development, where the routes and controllers do not exist.

premerge.sh at 6eaaaa8: phpunit 1804, vitest 1373, phpmd, phpstan, phpcs, format, lint, l10n, gate-16 and gate-25 all green. The certificate commit after it is covered by AdminApplicationControllerTest and the contract test.

Owed

  • The Newman collection was not run locally. I did not want to create accounts on the shared instance. CI's Newman job is the first run (task 2.3).
  • The docs site build was not run.
  • Live check: on a local instance, create an app password for an Audit-only user. curl -u svc:<app password> -H 'OCS-APIRequest: true' .../apps/keepiq/api/v1/admin lists areas: ["audit"], and -X PUT .../api/v1/admin/policies answers 403.

Refs #772. Members (task 1.2) and the CI Newman run (2.3) are still open, so the change is not archived.

Add the v1 admin API for scripts, each endpoint guarded by one admin area
in Nextcloud's middleware: an index (any area), policies (Policies),
suite listing and offboarding (People), applications with registration,
approval, rejection, deletion and lease policy (Applications), and audit
events, compliance reports and SIEM sinks (Audit). Writes carry a user
rate limit. Force revocation and reinstatement stay out: both need a
fresh password confirmation.

docs/api/admin-v1.openapi.json describes every route (OpenAPI 3.1, linted
by a new workflow); AdminApiContractTest keeps it, the route table and the
index in step, and checks each route's area guard. A Newman collection
seeds an Audit-only service account and checks its refusals. The member
overview waits on #895.

Refs #772
…dmin/applications/{id}

The Terraform provider registers an application from a CSR and needs the
certificate Keepiq signed. Additive to v1.

Refs #772
@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/keepiq @ 32646d0

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-manifest ✅
test-l10n ✅
format ✅
check-l10n-js ✅
check-schema-l10n ✅
composer ✅ ✅ 114/114
npm ✅ ✅ 660/660
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ❌
Newman ❌
Playwright ⏭️ deferred: E2E runs locally and on the promotion path only. This pull request targets development, so the suite is asked once per promotion into beta and main rather than once per push per open pull request. Run it locally with npx playwright test, or from the Actions tab on a branch with no open pull request into development.
Hydra gates ❌

Quality workflow — 2026-10-02 19:02 UTC

Download the full PDF report from the workflow artifacts.

…e index

The member overview from #965 already sits at /api/v1/admin/members with a
People area guard. Add it to the OpenAPI document (query parameters, row
shape), the index path list and the docs page, and a contract test that
ties the documented parameters, row fields and statuses to the controller
and service. Task 1.2 is done.

Refs #772
@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/keepiq @ fa8046b

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-manifest ✅
test-l10n ✅
format ✅
check-l10n-js ✅
check-schema-l10n ✅
composer ✅ ✅ 114/114
npm ✅ ✅ 660/660
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ❌
Newman ❌
Playwright ⏭️ deferred: E2E runs locally and on the promotion path only. This pull request targets development, so the suite is asked once per promotion into beta and main rather than once per push per open pull request. Run it locally with npx playwright test, or from the Actions tab on a branch with no open pull request into development.
Hydra gates ✅

Quality workflow — 2026-10-02 22:20 UTC

Download the full PDF report from the workflow artifacts.

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/keepiq @ 7c6a7ec

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-manifest ✅
test-l10n ✅
format ✅
check-l10n-js ✅
check-schema-l10n ✅
composer ✅ ✅ 114/114
npm ✅ ✅ 660/660
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ❌
Newman ❌
Playwright ⏭️ deferred: E2E runs locally and on the promotion path only. This pull request targets development, so the suite is asked once per promotion into beta and main rather than once per push per open pull request. Run it locally with npx playwright test, or from the Actions tab on a branch with no open pull request into development.
Hydra gates ✅

Quality workflow — 2026-10-02 22:31 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde

Copy link
Copy Markdown
Contributor Author

Members (task 1.2) is done in 3cbbfe5: GET /api/v1/admin/members (MemberOverviewController from #965, People guard) is in the OpenAPI document, the index and the docs page, and AdminApiContractTest::testTheMembersOperation ties its parameters, row fields and statuses to the controller and service. premerge2.sh at ffe9c74: phpunit 1908 OK, vitest 1482, phpmd, phpstan, phpcs, format, lint, l10n, gate-16 and gate-25 all green.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant