django-admin-mcp-api is a protocol-only adapter. Everything below is
either an invariant of the adapter itself or a deliberate decision to defer
the question to django-admin-rest-api.
Open a private security advisory at https://github.com/MartinCastroAlvarez/django-admin-mcp-api/security/advisories/new. Do not open a public issue for a suspected vulnerability.
If the issue is in the underlying REST API, report it to
django-admin-rest-api
instead — that is where the fix will land.
We respond within 5 business days.
django-admin-mcp-api only does two things:
- Accept an authenticated HTTP request from the consumer's Django stack.
- Translate an MCP JSON-RPC call into the equivalent
django-admin-rest-apiHTTP request and forward it.
It owns:
- The JSON-RPC envelope shape.
- The tool catalogue and the per-tool JSON-Schema validation.
- The "is the user signed in as staff?" baseline gate.
It does not own — and the code in this repo must never own:
- Any database query.
- Any permission check beyond the staff gate (per-tool permission is enforced inside rest-api).
- Any field serialization or form processing.
- Any new feature, validation rule, or behaviour that does not already exist in rest-api.
Trying to add one of those here is a bug. Open the change against
django-admin-rest-api instead.
These are enforced by pre-commit hooks and by tests/test_security.py.
If a rule is failing, fix the code — never relax the check.
- CSRF always on. No view in
django_admin_mcp_api/is@csrf_exempt. Theno-csrf-exemptpygrep hook fails the commit. - No direct DB access in the adapter.
Model.objects.all()andModel.objects.filter()are forbidden indjango_admin_mcp_api/server/. Querysets come fromModelAdmin.get_queryset(request)— inside rest-api. - No
user.has_perm()calls. Permission checks belong to rest-api. - Staff-only by default.
ALLOW_ANONYMOUS = Trueis a test-only escape hatch. Setting it in production is a security incident. - No new endpoints. The shipped URL conf exposes exactly
/(MCP JSON-RPC) and/manifest/(read-only catalogue). Any other endpoint is out of scope for this package.
- Nothing token-shaped lives in the repo.
gitleaks protectplus a localno-partial-tokenspygrep hook block any string matchingghp_,gho_,ghs_,github_pat_,aws_secret_access_key,AKIA[0-9A-Z]{16}, orBEGIN (RSA|EC|OPENSSH) PRIVATEfrom entering the index. The hook excludes its own definition,SECURITY.md(this file), andtests/test_security.py(which references the patterns to enforce them). - No
.envis tracked..envis in.gitignore;.env.exampleis the only env file ever committed. - The MCP wire never logs request bodies that look like secrets. Password set/change calls forward to rest-api's password form — the cleartext password is never logged by this package.
pip-auditruns in CI on every PR. Vulnerable dependencies block merge.- Dependabot is enabled for Python and GitHub Actions.
- Direct dependencies are minimal by design: Django, plus
django-admin-rest-api(once published). Everything else is a dev dependency.
- Releases are built with
poetry buildand uploaded to PyPI by a human + GitHub Actions on a tagged commit. Trusted-Publisher authentication is enabled; we never put a long-lived PyPI token in the repo. - The release script lives in
scripts/build.shand is reviewable.
Past advisories will be listed here once the package has shipped a v0.1.0 to PyPI.