Skip to content
Merged
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: 6 additions & 2 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ frontend/node_modules/
frontend/.next/
frontend/out/

# Docs / non-runtime
docs/
# Non-runtime. docs/ is NOT excluded: its markdown ships to /app/API/Docs and is indexed at
# runtime by the SearchDocs MCP tool (Get-CippDocsIndex). Only the image tree is dropped.
# This file is what applies to Dockerfile.release, which has no <dockerfile>.dockerignore of
# its own — so excluding docs/ here breaks the release image's `COPY docs`, while leaving the
# dev image (which reads build/Dockerfile.dockerignore) working. Keep the two in step.
docs/.gitbook/
.env
build/.env.example

Expand Down
431 changes: 431 additions & 0 deletions backend/Config/DocsPublishedPages.txt

Large diffs are not rendered by default.

75 changes: 75 additions & 0 deletions backend/Config/DocsSynonyms.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{
"_comment": "Query-expansion map for the SearchDocs MCP tool (Find-CippDoc). Keys are matched against the caller's query after tokenisation and stemming, so write them as ordinary words; the loader stems them. Values are expansion phrases scored at a damped weight, which is what lets a search for 'CA policy' reach pages that only ever say 'conditional access'. This is where most of the perceived semantic behaviour comes from without an embedding model, so it is worth extending whenever a real search misses.",
"expansions": {
"ca": ["conditional access policy"],
"mfa": ["multifactor authentication", "multi factor"],
"2fa": ["multifactor authentication"],
"sso": ["single sign on", "saml", "identity provider"],
"gdap": ["granular delegated admin privileges", "delegated access", "relationship"],
"dap": ["delegated admin privileges"],
"sam": ["secure application model", "service account", "application registration"],
"bec": ["business email compromise", "compromise remediation", "indicators of compromise"],
"bpa": ["best practice analyser", "report builder"],
"cis": ["compliance benchmark test"],
"spf": ["domain analyser", "email authentication", "dns record"],
"dkim": ["domain analyser", "email authentication", "dns record"],
"dmarc": ["domain analyser", "email authentication", "dns record"],
"dns": ["domain analyser", "domain health"],
"offboard": ["offboarding user removal"],
"onboard": ["onboarding tenant setup wizard"],
"standard": ["drift remediation baseline template"],
"drift": ["standards deviation baseline"],
"alert": ["alerting notification webhook"],
"tenant": ["customer client organisation"],
"intune": ["endpoint manager device management"],
"autopilot": ["device enrolment provisioning"],
"defender": ["security threat protection antivirus"],
"exchange": ["exchange online mailbox email"],
"exo": ["exchange online"],
"spam": ["spamfilter quarantine mail flow"],
"quarantine": ["spamfilter released message"],
"mailbox": ["exchange mailbox permissions shared"],
"license": ["licence sku subscription assignment"],
"licence": ["license sku subscription assignment"],
"sku": ["license subscription"],
"role": ["permission access rbac custom role"],
"permission": ["role access rbac consent"],
"rbac": ["role based access control permission"],
"log": ["audit log logbook activity history"],
"audit": ["log logbook activity history"],
"webhook": ["notification alert subscription"],
"psa": ["integration halo autotask connectwise"],
"rmm": ["integration ninja datto syncro"],
"backup": ["restore recovery export"],
"restore": ["backup recovery import"],
"template": ["policy blueprint preset"],
"policy": ["template configuration profile"],
"group": ["distribution list security group team"],
"user": ["account identity member"],
"password": ["credential reset passwordless authentication method"],
"device": ["endpoint computer workstation managed device"],
"app": ["application enterprise application service principal"],
"application": ["app enterprise application service principal"],
"sharepoint": ["onedrive site document library"],
"onedrive": ["sharepoint site storage"],
"teams": ["team channel meeting collaboration"],
"report": ["reporting export dashboard analytics"],
"dashboard": ["overview home report"],
"scheduler": ["scheduled task recurring job cron"],
"queue": ["scheduled task job processing"],
"error": ["troubleshooting failure issue problem"],
"fail": ["troubleshooting error issue problem"],
"troubleshoot": ["error failure diagnostic issue"],
"install": ["deployment setup provisioning"],
"deploy": ["installation setup provisioning"],
"upgrade": ["update version migration"],
"update": ["upgrade version release"],
"api": ["endpoint integration rest client"],
"mcp": ["model context protocol tool integration"],
"copilot": ["microsoft copilot ai"],
"hosted": ["cyberdrain hosted managed instance sponsor"],
"selfhost": ["self hosted azure deployment"],
"azure": ["subscription resource group function app"],
"graph": ["microsoft graph api request"]
}
}
151 changes: 143 additions & 8 deletions backend/Config/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -4670,10 +4670,20 @@
}
},
"TemplateGuid": {
"type": "string"
"type": "string",
"description": "The deploy drawer and wizard send the chosen row's GUID as TemplateList.value, not as TemplateID. Template display names are not unique - re-imports create same-named twins - so resolving by display name below can land on a different row than the one the user picked. The selected RowKey must win whenever the request carries one. String rather than Guid: built-in templates are stored with their filename as RowKey."
},
"TemplateID": {
"type": "string"
"type": "string",
"description": "The deploy drawer and wizard send the chosen row's GUID as TemplateList.value, not as TemplateID. Template display names are not unique - re-imports create same-named twins - so resolving by display name below can land on a different row than the one the user picked. The selected RowKey must win whenever the request carries one. String rather than Guid: built-in templates are stored with their filename as RowKey."
},
"TemplateList": {
"allOf": [
{
"$ref": "#/components/schemas/LabelValue"
}
],
"description": "The deploy drawer and wizard send the chosen row's GUID as TemplateList.value, not as TemplateID. Template display names are not unique - re-imports create same-named twins - so resolving by display name below can land on a different row than the one the user picked. The selected RowKey must win whenever the request carries one. String rather than Guid: built-in templates are stored with their filename as RowKey."
},
"TemplateType": {
"type": "string"
Expand Down Expand Up @@ -38916,6 +38926,86 @@
"x-cipp-role": "CIPP.Core.Read"
}
},
"/api/ListCippDocs": {
"get": {
"summary": "Search the CIPP documentation, or fetch one documentation page in full.",
"operationId": "ListCippDocs",
"tags": [
"CIPP > Core"
],
"description": "Searches the GitBook documentation shipped with this build and returns matching sections,\neach with an excerpt and links back to docs.cipp.app and to the file on GitHub. Pages under\nuser-documentation also report the CIPP route they document, so a screen can be traced to\nits docs and back.\n\nPass path on its own to list the pages under a documentation subtree or a CIPP route, or\nwith full=true to return one page's entire text. This backs the SearchDocs and GetDoc MCP\ntools and is available to the UI and API clients on the same terms.",
"parameters": [
{
"name": "full",
"in": "query",
"description": "Return the whole page rather than matching sections. Requires path.",
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "limit",
"in": "query",
"description": "Maximum results to return (default 8, max 25).",
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "path",
"in": "query",
"description": "A documentation subtree ('user-documentation/identity') or a CIPP route ('/identity/administration/users').",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "query",
"in": "query",
"description": "Keywords or a plain-language question, e.g. 'how do I set up GDAP'.",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"description": "Not described statically: this endpoint returns the upstream response as-is, so its fields are determined by the upstream API rather than by CIPP. Call the endpoint to see the actual shape, or add a response schema in backend/Config/openapi-overrides."
}
}
}
}
},
"401": {
"description": "Unauthorized - invalid or missing bearer token"
},
"403": {
"description": "Forbidden - caller lacks the required RBAC role"
},
"500": {
"description": "Internal server error"
}
},
"security": [
{
"bearerAuth": []
}
],
"x-cipp-role": "CIPP.Core.Read",
"x-cipp-any-tenant": true
}
},
"/api/ListCippQueue": {
"get": {
"summary": "ListCippQueue",
Expand Down Expand Up @@ -46309,21 +46399,24 @@
"type": "object",
"description": "Derived from the fields written into the storage table it reads, and the fields the endpoint selects onto each record, and the columns the CIPP UI renders. Fields taken from the storage writers may be omitted by this endpoint, and the response may carry computed fields not listed here.",
"properties": {
"corrupt": {
"x-cipp-field-source": "backend"
},
"description": {
"x-cipp-field-source": "frontend"
"x-cipp-field-source": "backend,frontend"
},
"displayName": {
"x-cipp-field-source": "frontend"
"x-cipp-field-source": "backend,frontend"
},
"ETag": {
"type": "string",
"x-cipp-field-source": "storage"
},
"guid": {
"x-cipp-field-source": "storage"
"x-cipp-field-source": "storage,backend"
},
"isSynced": {
"x-cipp-field-source": "frontend"
"x-cipp-field-source": "backend,frontend"
},
"JSON": {
"x-cipp-field-source": "storage"
Expand All @@ -46332,7 +46425,7 @@
"x-cipp-field-source": "backend"
},
"package": {
"x-cipp-field-source": "storage,frontend"
"x-cipp-field-source": "storage,backend,frontend"
},
"PartitionKey": {
"x-cipp-field-source": "storage"
Expand All @@ -46348,7 +46441,7 @@
"x-cipp-field-source": "storage"
},
"source": {
"x-cipp-field-source": "storage"
"x-cipp-field-source": "storage,backend"
},
"templateCount": {
"x-cipp-field-source": "backend"
Expand Down Expand Up @@ -49144,6 +49237,48 @@
"x-cipp-role": "Tenant.Relationship.Read"
}
},
"/api/ListPartnerTenantInfo": {
"get": {
"summary": "ListPartnerTenantInfo",
"operationId": "ListPartnerTenantInfo",
"tags": [
"CIPP > Core"
],
"description": "Reports whether the CIPP host tenant is a Microsoft Partner tenant, so the frontend can\ndecide whether partner-only flows (GDAP onboarding, reseller invites, GDAP permission\nchecks) apply to this instance.\n\nMarked AnyTenant deliberately. This answers a question about the CIPP instance, not\nabout a tenant the caller wants to act on, and Get-CippPartnerTenantInfo pins the lookup\nto $env:TenantID. Without the flag, Test-CIPPAccess falls back to $env:TenantID as the\ntenant filter and denies any custom role that blocks the partner tenant, which silently\ngreys out partner-only UI for roles that are otherwise fully permitted.",
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"description": "Not described statically: this endpoint returns the upstream response as-is, so its fields are determined by the upstream API rather than by CIPP. Call the endpoint to see the actual shape, or add a response schema in backend/Config/openapi-overrides."
}
}
}
}
},
"401": {
"description": "Unauthorized - invalid or missing bearer token"
},
"403": {
"description": "Forbidden - caller lacks the required RBAC role"
},
"500": {
"description": "Internal server error"
}
},
"security": [
{
"bearerAuth": []
}
],
"x-cipp-role": "CIPP.Core.Read",
"x-cipp-any-tenant": true
}
},
"/api/ListPendingWebhooks": {
"get": {
"summary": "ListPendingWebhooks",
Expand Down
Loading
Loading