DeepWiki Hardening Guide
Security configuration for Cognition DeepWiki: public/private repository boundaries, indexing scope, credential-free public MCP, isolated research clients, and reviewed wiki configuration.
Overview
This is a product guide within the Cognition platform. Cognition’s DeepWiki MCP announcement establishes the product’s ownership. Private DeepWiki uses Devin’s organization and repository controls; the public service does not inherit a customer’s Devin SSO, roles, or network policy. Apply the Devin common controls for private organization access rather than configuring a second identity plane here.
Two different trust boundaries: deepwiki.com and mcp.deepwiki.com serve public GitHub repository documentation. Private repository research belongs in the Devin application or the authenticated Devin MCP service. The latter is not simply a private copy of the public read-only connector: it also exposes platform-management capabilities. DeepWiki MCP and Devin MCP document the distinction.
Product Editions Covered: Free public DeepWiki and private repository wikis within a Devin account. Enterprise repository permissions are identified explicitly. This guide does not assume that a free public-service operator has a tenant administration console.
Validation status: Documentation checked on 2026-10-29; local configuration checks were exercised with synthetic fixtures. No private tenant, live client integration, or repository authorization boundary was tested. There is no human-review or live-validation claim.
Intended Audience
- Security and developer-platform teams approving repository documentation services
- Repository owners reviewing what is indexed and how generated content is consumed
- Administrators connecting MCP clients to DeepWiki
How to Use This Guide
- L1 (Crawl): Keep public and private research separate, and use the documented public endpoint without credentials.
- L2 (Walk): Audit indexing scope, isolate research clients, and review repository-native generation configuration.
- Apply controls to the surface they name; a client-side check is not server-side enforcement.
Scope
This guide addresses DeepWiki-specific data routing, indexing, MCP consumption, and wiki configuration. Devin SSO, service-user roles, repository access grants, audit logs, and agent-execution policy belong in the Devin guide. Local execution and client approval rules belong in the Devin CLI and Devin Desktop guides.
No named Devin or DeepWiki CIS Benchmark or CISA SCuBA baseline was identified in the 2026-10-29 research. A generic CIS AI MCP Server benchmark exists but is not a product-specific baseline for this hosted service. DISA product coverage remains inconclusive because its index could not be fully verified; no DeepWiki-specific NSA or ACSC configuration guidance was identified. The NIST mappings below are supporting control objectives, not a certification or an independent product benchmark.
Table of Contents
- Repository and Data Boundaries
- MCP Client Boundaries
- Documentation Configuration
- Compliance Quick Reference
1. Repository and Data Boundaries
1.1 Keep Private Research in the Authenticated Devin Boundary
Profile Level: L1 (Crawl)
| Framework | Control |
|---|---|
| NIST 800-53 Rev. 5 | AC-3, AC-6 |
Description
Use the public DeepWiki service only for information approved for public disclosure. Route private code, incident details, customer information, and private repository questions through your authorized Devin organization. A public repository name does not make a prompt containing internal context public-safe.
Rationale
Why This Matters:
- Public repository research needs no credential; adding one increases exposure without providing private access.
- A question can reveal sensitive context even when its answer is derived entirely from public code.
Attack Prevented: Accidental disclosure through a public research connector and over-broad private repository access.
Prerequisites
- A data-classification decision for the intended prompt and repository
- For private work, an authorized Devin account and approved SCM repository grants
ClickOps Implementation
- For public research, open deepwiki.com and select an approved public repository. Do not paste private source or secrets into its questions.
- For private research, open the approved organization in app.devin.ai and use its DeepWiki or Ask Devin interface.
- Have the Devin administrator enforce the repository grants described in Devin section 3.1. On Enterprise, the documented review location is Settings > Repositories; choose the organization and inspect its configured permissions. Prefer individual repositories over broad SCM groups.
- Keep a record of which organization is authorized for each private repository; do not treat indexing or wiki steering as an access grant.
The public/private product split is documented by Cognition; Enterprise grant semantics and navigation are documented in Git Integrations.
Automation: The human data-classification decision is not a DeepWiki API setting. Repository authorization is administered and audited through the Devin common controls, not a fabricated DeepWiki SSO or ACL API. Public MCP documentation, checked 2026-10-29, documents public research tools only.
Validation & Testing
- In a non-production test, confirm that an approved user can access the intended private repository and an unapproved user or organization cannot. Use harmless test content; never test by submitting real secrets publicly.
- Treat a missing or empty answer as inconclusive, not proof of authorization denial. Record the explicit access result.
- Recheck the boundary after membership or SCM grant changes. Escalate residual indexed-data access to Cognition rather than assuming revocation proves deletion.
Compliance Mappings
| Framework | Control ID | Control Description |
|---|---|---|
| NIST 800-53 Rev. 5 | AC-3 | Enforce authorized information access |
| NIST 800-53 Rev. 5 | AC-6 | Limit access to required repositories |
1.2 Review Indexed Repositories and Additional Branches
Profile Level: L2 (Walk)
| Framework | Control |
|---|---|
| NIST 800-53 Rev. 5 | AC-6, CM-8 |
Description
Maintain an approved inventory of repositories and branches that DeepWiki indexes. Include repositories added through environment configuration: creating a development environment is not the only workflow that matters to documentation scope.
Rationale
Why This Matters:
- Old feature or incident branches can contain information outside the intended documentation scope.
- Comparing the current inventory with approvals exposes additions that an initial onboarding review will miss.
Attack Prevented: Unreviewed expansion of the source material available to code-search and documentation consumers.
ClickOps Implementation
- In the intended Devin organization, open Settings > DeepWiki > Repositories.
- Compare the listed repositories with the approved inventory. The vendor documents automatic indexing for repositories added to an environment or blueprint.
- Click each repository to open Indexed branches. Review additional branches as well as the default branch.
- Use Add > Add repositories or Add branch only for an approved addition. If an entry is no longer approved, stop using it and have the administrator reconcile both repository authorization and indexing. The API has documented repository and branch removal operations; their writes are not executed by these inventory packs.
These indexing paths and automatic-indexing behaviors come from Index a Repository. That page does not document an index-purge or retention guarantee; do not interpret permission removal as proof that stored documentation was deleted.
Code Implementation
Code Pack: Terraform
terraform {
required_providers {
devin = {
source = "cognitionai/devin"
version = "= 0.5.0"
}
}
}
provider "devin" {
# DEVIN_TOKEN is injected by your approved secret manager, never committed.
api_url = "https://api.devin.ai"
}
variable "deepwiki_org_id" {
type = string
description = "The approved Devin organization to inventory."
validation {
condition = can(regex("^org-[A-Za-z0-9_-]+$", var.deepwiki_org_id))
error_message = "Supply a Devin organization ID with the org- prefix."
}
}
data "devin_repositories" "deepwiki_inventory" {
org_id = var.deepwiki_org_id
}
output "deepwiki_repository_indexing_flags" {
description = "Review against approvals; not an indexed-branch inventory or a compliance verdict."
sensitive = true
value = [for repository in data.devin_repositories.deepwiki_inventory.repositories : {
repository_path = repository.repository_path
indexing_enabled = repository.indexing_enabled
}]
}
Code Pack: API Script
set +x
set -euo pipefail
umask 077
if [[ $# -ne 0 ]]; then
echo "Usage: inject DEVIN_API_KEY and DEVIN_ORG_ID, then run this script with no arguments" >&2
exit 2
fi
for tool in curl python3; do
command -v "$tool" >/dev/null 2>&1 || { echo "PRECONDITION: $tool required" >&2; exit 2; }
done
if [[ ! "${DEVIN_API_KEY:-}" =~ ^cog_[A-Za-z0-9._-]+$ || ! "${DEVIN_ORG_ID:-}" =~ ^org-[A-Za-z0-9_-]+$ ]]; then
echo "PRECONDITION: inject a current cog_ credential and an org- organization ID" >&2
exit 2
fi
work=$(mktemp -d)
trap 'rm -rf -- "$work"' EXIT
printf '%s' '{"items":[],"cursors":[]}' > "$work/state.json"
cursor=""
for ((page = 1; page <= 1000; page++)); do
query=(--data-urlencode "first=200")
[[ -z "$cursor" ]] || query+=(--data-urlencode "after=$cursor")
# Authorization travels over stdin, not argv. Only a GET is issued.
if ! status=$(curl --disable --silent --show-error --fail \
--proto '=https' --tlsv1.2 --connect-timeout 10 --max-time 60 \
--max-filesize 20971520 \
--config - --get "https://api.devin.ai/v3/organizations/$DEVIN_ORG_ID/repositories/indexing" \
"${query[@]}" --output "$work/page.json" --write-out '%{http_code}' <<EOF
header = "Authorization: Bearer $DEVIN_API_KEY"
header = "Accept: application/json"
EOF
); then
echo "UNKNOWN: inventory request failed (HTTP ${status:-unavailable}); no complete inventory produced" >&2
exit 2
fi
if [[ "$status" != "200" ]]; then
echo "UNKNOWN: unexpected HTTP status; no complete inventory produced" >&2
exit 2
fi
if ! python3 - "$work" <<'PY'
import json
import pathlib
import sys
root = pathlib.Path(sys.argv[1])
try:
if (root / "page.json").stat().st_size > 20 * 1024 * 1024:
raise ValueError("oversized response")
page = json.loads((root / "page.json").read_text(encoding="utf-8"))
state = json.loads((root / "state.json").read_text(encoding="utf-8"))
if not isinstance(page, dict) or not isinstance(page.get("items"), list):
raise ValueError("invalid page")
# HTH fail-closed policy requires explicit pagination even though OpenAPI
# supplies a default false flag. An omitted field is not completeness proof.
next_page = page["has_next_page"]
cursor = page["end_cursor"]
if type(next_page) is not bool or (cursor is not None and not isinstance(cursor, str)):
raise ValueError("invalid pagination")
if next_page and (not cursor or cursor in state["cursors"] or any(ord(c) < 32 for c in cursor)):
raise ValueError("invalid or repeated cursor")
known = {item["repository_path"] for item in state["items"]}
for item in page["items"]:
if not isinstance(item, dict):
raise ValueError("invalid item")
path, enabled, branches = item.get("repository_path"), item.get("indexing_enabled"), item.get("branches")
if not isinstance(path, str) or not path or path in known or type(enabled) is not bool:
raise ValueError("invalid repository")
if not isinstance(branches, list) or not all(isinstance(branch, str) for branch in branches):
raise ValueError("invalid branches")
known.add(path)
state["items"].append({"repository_path": path, "indexing_enabled": enabled, "branches": branches})
if next_page:
state["cursors"].append(cursor)
(root / "state.json").write_text(json.dumps(state), encoding="utf-8")
(root / "cursor").write_text(cursor if next_page else "", encoding="utf-8")
except (OSError, UnicodeError, ValueError, TypeError, KeyError, RecursionError):
print("UNKNOWN: invalid or inconsistent API response; no complete inventory produced", file=sys.stderr)
sys.exit(2)
PY
then
exit 2
fi
cursor=$(cat "$work/cursor")
if [[ -z "$cursor" ]]; then
python3 - "$work/state.json" <<'PY'
import json
import sys
with open(sys.argv[1], encoding="utf-8") as source:
items = json.load(source)["items"]
print(json.dumps({"complete": True, "repository_count": len(items), "repositories": sorted(items, key=lambda row: row["repository_path"])}, indent=2))
PY
echo "Inventory complete; compare repositories and branches with your approved scope. No compliance verdict." >&2
exit 0
fi
done
echo "UNKNOWN: exceeded 1000 pages; no complete inventory produced" >&2
exit 2
The API pack uses the documented List indexed repositories endpoint and follows every cursor. Inject DEVIN_API_KEY and DEVIN_ORG_ID through your approved credential manager. A scoped service user needs access to the target organization’s repository inventory; missing permissions or a malformed response are unknown, not a clean audit. Output contains private repository names and branches: keep it in protected evidence storage.
The official Terraform provider data source reports connected repositories and indexing flags, but not branches. Its native devin_repository_indexing resource and the REST write routes can change indexing; these audit packs deliberately omit those writes. Creating an indexing resource starts jobs; destroying it disables indexing and clears configured branches. Review a separate change plan instead of adopting an auto-index-all example. Terraform format checks passed. Provider initialization was attempted with backends disabled on 2026-10-30, but the official registry connection timed out; provider-backed validation, plan, and apply were not performed. The pack was source-checked against provider v0.5.0.
Validation & Testing
- Record the organization, repository, branches, owner, and approval date in the organization’s protected inventory.
- Resolve every unexpected entry with the repository owner. Recheck after environment changes and at least monthly.
- A connected repository list is not interchangeable with the indexed repository or branch list.
Compliance Mappings
| Framework | Control ID | Control Description |
|---|---|---|
| NIST 800-53 Rev. 5 | AC-6 | Constrain data access to the intended purpose |
| NIST 800-53 Rev. 5 | CM-8 | Maintain an inventory of in-scope components |
2. MCP Client Boundaries
2.1 Use the Credential-Free Official Public MCP Endpoint
Profile Level: L1 (Crawl)
| Framework | Control |
|---|---|
| NIST 800-53 Rev. 5 | CM-6, SC-8 |
Description
Configure public DeepWiki directly at https://mcp.deepwiki.com/mcp, with no authentication header, API key, or package-execution wrapper. The configuration pack is a template to merge into an approved client, not a command that overwrites an existing file.
Rationale
Why This Matters:
- An exact HTTPS destination avoids look-alike endpoints and unnecessary local package execution.
- A credential-free configuration cannot accidentally send a Devin key to a public connector.
Attack Prevented: Credential leakage to unnecessary endpoints and substitution of an unapproved local MCP wrapper.
ClickOps Implementation
- Open your approved client’s MCP configuration editor. For Devin Desktop Cascade, use the panel’s … (Actions) > MCPs > Open MCP config file. Devin Local uses the separate CLI configuration workflow; follow the Devin CLI guide.
- Add the public template from the pack below without replacing unrelated approved settings.
- Confirm the server is remote HTTPS and has no headers or credentials. The standard
urlfield is documented; Desktop also acceptsserverUrl. - Reconnect and inspect the tool inventory: the documented public tools are
read_wiki_structure,read_wiki_contents, andask_question. Investigate unexpected tools before use.
Sources: DeepWiki MCP configuration and tools and Cascade MCP configuration editor. The /sse endpoint is legacy and being deprecated, not the recommended transport.
Code Implementation
Code Pack: Config
{
"mcpServers": {
"deepwiki": {
"url": "https://mcp.deepwiki.com/mcp"
}
}
}
Validation & Testing
- Review the effective loaded URL, not only the file you edited. A client can silently ignore an unsupported configuration field.
- Use the read-only audit pack in control 2.2 for a dedicated public-research profile.
- Query a harmless approved public repository. Successful public queries do not establish private-repository authorization.
Compliance Mappings
| Framework | Control ID | Control Description |
|---|---|---|
| NIST 800-53 Rev. 5 | CM-6 | Set and verify approved configuration values |
| NIST 800-53 Rev. 5 | SC-8 | Protect transmission to the approved HTTPS endpoint |
2.2 Isolate Public Research from Authenticated Agent Tools
Profile Level: L2 (Walk)
| Framework | Control |
|---|---|
| NIST 800-53 Rev. 5 | AC-6, CM-7 |
Description
Use a dedicated public-research client configuration that contains only the public DeepWiki connector. Do not silently substitute authenticated Devin MCP. The pack verifies a conservative local profile; it does not claim to sandbox the client or inspect its other configuration layers.
Rationale
Why This Matters:
- Authenticated Devin MCP can manage sessions, playbooks, knowledge, and schedules, beyond answering repository questions.
- Documentation returned by a public repository is untrusted input; placing it next to privileged tools creates an avoidable escalation path.
Attack Prevented: Confusing a documentation-only connector with an authenticated agent-management integration, and inadvertent exposure of privileged tools to untrusted research content.
ClickOps Implementation
- Create or select a dedicated configuration using your client’s supported profile mechanism. If it cannot isolate profiles, use a separate client instance or keep the authenticated connector disconnected during public research.
- Configure only the public DeepWiki entry from control 2.1. Disable other MCP servers, native execution tools, automatic tool approval, and private-context attachments through the client’s documented controls. See the CLI or Desktop guide for those separate surfaces.
- If private research is required, switch to a separately approved workflow. Review the service user’s permissions and the actual discovered tool list before enabling Devin MCP. The Devin hub covers service-user authorization.
- Do not rely on the server name
deepwikias a trust decision. Inspect the URL and effective capabilities.
The authenticated service’s expanded capability set is documented in Devin MCP. Isolation is this guide’s compensating control, not a claimed DeepWiki server-side policy.
Code Implementation
Code Pack: Config
set -euo pipefail
if [[ $# -ne 1 ]]; then
echo "Usage: $0 /path/to/dedicated-mcp.json" >&2
exit 2
fi
command -v python3 >/dev/null 2>&1 || { echo "PRECONDITION: python3 required" >&2; exit 2; }
python3 - "$1" <<'PY'
import json
import sys
def unique_object(pairs):
result = {}
for key, value in pairs:
if key in result:
raise ValueError("duplicate key")
result[key] = value
return result
try:
with open(sys.argv[1], encoding="utf-8") as source:
raw = source.read(1024 * 1024 + 1)
if len(raw) > 1024 * 1024:
raise ValueError("oversized input")
config = json.loads(raw, object_pairs_hook=unique_object)
except (OSError, UnicodeError, ValueError, RecursionError):
print("UNKNOWN: file is unreadable, oversized, or invalid JSON", file=sys.stderr)
sys.exit(2)
ok = isinstance(config, dict) and set(config) == {"mcpServers"}
servers = config.get("mcpServers") if isinstance(config, dict) else None
ok = ok and isinstance(servers, dict) and set(servers) == {"deepwiki"}
entry = servers.get("deepwiki") if isinstance(servers, dict) else None
if isinstance(entry, dict):
# Exactly one URL spelling; reject ambiguous precedence and extra settings.
ok = ok and set(entry) in ({"url"}, {"serverUrl"})
endpoint = entry.get("url", entry.get("serverUrl"))
ok = ok and endpoint == "https://mcp.deepwiki.com/mcp"
else:
ok = False
if not ok:
print("FINDING: profile is not an isolated, credential-free official DeepWiki configuration")
sys.exit(1)
print("PASS: supplied file has only the credential-free official DeepWiki entry")
print("NOT PROVEN: effective client tools, inherited config, plugins, prompt safety, or server behavior")
PY
Run the script with the path to the dedicated MCP JSON file. Exit 0 means that file matches this narrow policy; 1 reports a configuration finding; 2 means it could not be assessed. It reads no credentials into output, performs no network requests, and writes no files. It intentionally rejects extra servers and unrecognized fields instead of certifying a mixed-use profile.
Validation & Testing
- Confirm the live client’s complete tool inventory matches the isolated workflow; the file check alone cannot see plugins, built-in tools, inherited settings, or environment-injected connections.
- Confirm automatic execution remains disabled in the client and that external documentation cannot grant approvals.
- Re-run the audit after edits. Treat an audit failure as a review requirement, not permission to delete other configurations automatically.
Compliance Mappings
| Framework | Control ID | Control Description |
|---|---|---|
| NIST 800-53 Rev. 5 | AC-6 | Keep research separate from privileged actions |
| NIST 800-53 Rev. 5 | CM-7 | Expose only needed capabilities |
3. Documentation Configuration
3.1 Review Wiki Generation Configuration as Repository Content
Profile Level: L2 (Walk)
| Framework | Control |
|---|---|
| NIST 800-53 Rev. 5 | CM-3, CM-6 |
Description
Review changes to .devin/wiki.json with the repository’s normal change-control process. Validate the documented structure before regeneration and examine the resulting pages. The file directs generation; it is not an exclusion list, an authorization policy, or a guarantee that sensitive content cannot be read.
Rationale
Why This Matters:
- Repository-supplied instructions can change what readers see and which security-relevant areas receive attention.
- Schema validation catches malformed or incomplete plans, but cannot certify the factual accuracy or safety of their prose.
Attack Prevented: Unreviewed manipulation of generated documentation and false confidence in a prompt-based data-access boundary.
ClickOps Implementation
- Open
.devin/wiki.jsonin the repository editor. If no steering file is needed, leaving it absent is valid; do not add one merely to satisfy this guide. - If present, inspect
repo_notesand every page’stitle,purpose,parent, and optional notes. Reject secret values and instructions to bypass access controls or execute external actions. - Review the intended complete page set. This file replaces the default planning behavior; omitting a security topic may omit its page.
- After generation, follow the wiki’s source links and compare a sample of claims with the underlying code. Keep source permissions and repository review rules as the enforceable boundaries.
The documented file contract and limits are in DeepWiki repository wikis. The local validator checks required arrays, page-title uniqueness, repository-note limits, and hierarchy consistency. Additional hierarchy checks are explicitly HTH policy, not undocumented vendor guarantees. The vendor describes page_notes as an array but does not fully document its item structure; a nonempty array returns unknown / manual review required, not a fabricated schema verdict.
Code Implementation
Code Pack: Config
set -euo pipefail
if [[ $# -lt 1 || $# -gt 2 || ( $# -eq 2 && "$2" != "--enterprise" ) ]]; then
echo "Usage: $0 /path/to/.devin/wiki.json [--enterprise]" >&2
exit 2
fi
command -v python3 >/dev/null 2>&1 || { echo "PRECONDITION: python3 required" >&2; exit 2; }
python3 - "$@" <<'PY'
import json
import sys
def unique_object(pairs):
result = {}
for key, value in pairs:
if key in result:
raise ValueError("duplicate key")
result[key] = value
return result
try:
with open(sys.argv[1], encoding="utf-8") as source:
raw = source.read(4 * 1024 * 1024 + 1)
if len(raw) > 4 * 1024 * 1024:
raise ValueError("oversized input")
config = json.loads(raw, object_pairs_hook=unique_object)
except (OSError, UnicodeError, ValueError, RecursionError):
print("UNKNOWN: file is unreadable, oversized, or invalid JSON", file=sys.stderr)
sys.exit(2)
def fail(message):
print("FINDING: " + message)
sys.exit(1)
def nonblank(value):
return isinstance(value, str) and bool(value.strip())
if not isinstance(config, dict) or set(config) != {"repo_notes", "pages"}:
fail("required top-level keys are repo_notes and pages; unknown keys need review")
notes = config["repo_notes"]
pages = config["pages"]
max_pages = 80 if len(sys.argv) == 3 else 30
if not isinstance(notes, list) or not isinstance(pages, list) or not 1 <= len(pages) <= max_pages:
fail("notes/pages must be arrays with 1 to the plan's maximum pages")
all_notes = list(notes)
has_page_notes = False
parents = {}
for page in pages:
if not isinstance(page, dict) or not set(page) <= {"title", "purpose", "parent", "page_notes"}:
fail("invalid or unrecognized page fields")
title, purpose = page.get("title"), page.get("purpose")
if not nonblank(title) or not nonblank(purpose) or title in parents:
fail("page titles must be unique and nonblank; purposes must be nonblank")
parent = page.get("parent")
if parent is not None and not nonblank(parent):
fail("parent must be null or a nonblank page title")
parents[title] = parent
page_notes = page.get("page_notes", [])
if not isinstance(page_notes, list):
fail("page_notes must be an array")
has_page_notes = has_page_notes or bool(page_notes)
all_notes.extend(page_notes)
if len(all_notes) > 100:
fail("combined repo and page notes exceed 100")
for note in notes:
if not isinstance(note, dict) or not set(note) <= {"content", "author"}:
fail("invalid or unrecognized note fields")
content = note.get("content")
if not isinstance(content, str) or len(content) > 10000:
fail("note content must be a string of at most 10000 characters")
if "author" in note and not isinstance(note["author"], str):
fail("note author must be a string")
if has_page_notes:
print("UNKNOWN: nonempty page_notes require manual review; item schema is not fully documented")
sys.exit(2)
for title in parents:
seen = set()
current = title
while current is not None:
if current not in parents or current in seen:
fail("HTH hierarchy check: dangling parent or cycle")
seen.add(current)
current = parents[current]
print(f"PASS: structural checks passed for {len(pages)} page(s) and {len(all_notes)} note(s)")
print("NOT PROVEN: prose safety, generated accuracy, secret exclusion, or access control")
PY
Pass the JSON file path, and optionally --enterprise for the documented higher page limit. The default limit is 30 pages; Enterprise allows 80. The script never prints note text and never changes the file. Exit 0 means structural checks passed, not that the contents are safe or access-controlled.
Validation & Testing
- Run the validator before a configuration change is accepted; review prose separately.
- Test generated output against source references and report misleading or missing material.
- Do not test exclusions by placing real secrets in a repository. A sentence asking the model to ignore a file is not an ACL.
Compliance Mappings
| Framework | Control ID | Control Description |
|---|---|---|
| NIST 800-53 Rev. 5 | CM-3 | Review configuration changes |
| NIST 800-53 Rev. 5 | CM-6 | Check the supported configuration structure |
4. Compliance Quick Reference
These mappings identify supporting objectives in NIST SP 800-53 Rev. 5; they are not assertions that applying this guide satisfies an entire control.
| NIST control | DeepWiki practice | Guide sections |
|---|---|---|
| AC-3, AC-6 | Authorized private research and least-privilege scope | 1.1, 1.2, 2.2 |
| CM-3, CM-6 | Reviewed and checked configuration | 2.1, 3.1 |
| CM-7, CM-8 | Restricted capabilities and indexing inventory | 1.2, 2.2 |
| SC-8 | Approved HTTPS connection | 2.1 |
Appendix A: Edition and Automation Coverage
| Surface | Public DeepWiki | Private wikis within Devin |
|---|---|---|
| Repository source | Public GitHub repositories | Repositories authorized in the Devin organization |
| Identity | Public service; no login required for public MCP | Devin account and repository authorization; hub controls apply |
| MCP endpoint | https://mcp.deepwiki.com/mcp |
https://mcp.devin.ai/mcp; broader authenticated capabilities |
| Steering configuration | Review a repository’s steering file if used | .devin/wiki.json; 30-page limit or 80 for Enterprise |
| Validation here | Offline template and synthetic-fixture tests | No tenant or authorization test performed |
Automation Surface Census
The DeepWiki-specific surface review checked the product documentation index, the public MCP reference, the private MCP reference, and the wiki file reference on 2026-10-29. Four of five controls have a pack, spanning API, Terraform, and config. Public research is MCP-based; private indexing additionally uses the authenticated Devin API and provider.
| Surface | Verdict for these controls |
|---|---|
| Terraform | Available: devin_repositories data source (pack); devin_repository_indexing resource (documented write surface, deliberately not applied by the audit pack) |
| API / GraphQL | Available: Devin v3 repository indexing list/status and PUT/DELETE routes; read-only inventory pack. Public MCP itself is not a REST or GraphQL tenant-admin API; no GraphQL surface documented |
| CLI | No standalone DeepWiki administrative CLI documented; claude mcp add is a client command, not a Cognition CLI |
| SDK | No official DeepWiki administrative SDK documented in the reviewed index |
| Config | Available: MCP client JSON and .devin/wiki.json; template plus local read-only verification |
| SIEM | No public-service audit-export schema documented; Devin organization audit handling belongs in the hub |
Known limits: No documented public-service SSO, IP allowlist, per-organization DLP switch, or guaranteed private-data erasure is asserted here. Index-disable operations are not an assertion about retention or backup deletion. The local packs do not verify server identity beyond the configured literal URL, probe network behavior, enforce prompt classification, or make the consuming agent safe against all prompt injection.
Appendix B: References
- Cognition: The DeepWiki MCP Server
- DeepWiki repository wikis and configuration
- Index a Repository
- Enterprise Git Integrations
- Public DeepWiki MCP
- Authenticated Devin MCP
- List indexed repositories
- Official Terraform provider
- Cascade MCP Configuration
- NIST SP 800-53 Rev. 5
November 2026 boundary clarification
The public DeepWiki endpoint is https://mcp.deepwiki.com/mcp, with three credential-free read tools; legacy SSE is deprecated. Authenticated https://mcp.devin.ai/mcp is a different service: it can create/interact with sessions and manage knowledge, playbooks and schedules, not merely answer repository questions. Organization service keys select their organization; enterprise service keys and PATs require the documented X-Org-Id. Private Ask Devin can lead into a full app/session workflow. Apply hub roles, repository grants and credential policy before connecting it; do not reuse the public endpoint’s low-risk classification. Public MCP, authenticated MCP and DeepWiki retrieved 2026-11-05. The source-first ledger distinguishes read and write surfaces and unresolved inventory gaps.
Changelog
| Date | Version | Maturity | Changes | Author |
|---|---|---|---|---|
| 2026-11-05 | 0.1.1 | ai-drafted | Clarified credential-free public MCP versus authenticated management/session authority, Ask Devin and deprecated SSE; retained five stable controls. Documentation refresh only. | Codex (GPT-6) |
| 2026-10-30 | 0.1.0 | ai-drafted | Initial five-control guide; public/private boundary, indexing inventory, five API, Terraform, and configuration packs, and offline tests. No live tenant validation. | Codex |
Contributing
Report incorrect settings or propose improvements through GitHub issues. See the Contributing Guide before submitting changes.