Skip to content

feat: expose CIPP user sign-in logs (WYREAI-405) - #95

Draft
asachs01 wants to merge 1 commit into
mainfrom
cursor/list-user-signin-logs-8b46
Draft

asachs01 wants to merge 1 commit into
mainfrom
cursor/list-user-signin-logs-8b46

Conversation

@asachs01

@asachs01 asachs01 commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Exposes CIPP's existing user sign-in logs endpoint as the Conduit MCP tool cipp_list_user_signin_logs.

Linear: WYREAI-405

No CIPP-API changes. The handler already exists at Modules/CIPPHTTP/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSigninLogs.ps1 on KelvinTegelaar/CIPP-API master. Generic CIPP routing serves it as GET /api/ListUserSigninLogs.

Invoke-ListUserSigninLogs reads three query parameters and nothing else:

  • tenantFilter
  • UserID (this casing — not userId)
  • top (defaults to 50 when omitted)

It calls Graph GET /beta/auditLogs/signIns?$filter=(userId eq '<UserID>')&$top=<top>&$orderby=createdDateTime desc with -noPagination, so the response is one page of interactive sign-ins, newest first. Failures are HTTP 500 with the error string in the body.

The Graph userId property is the Entra object id. A UPN in UserID makes Graph reject the filter. The tool therefore accepts either an object id (sent straight through, so a deleted user's history stays queryable) or a UPN (resolved through ListUsers first). allTenants is rejected because the function has no all-tenants branch. top must be an integer from 1 to 1000, Graph's page size for this API.

Example tool call

{
  "name": "cipp_list_user_signin_logs",
  "arguments": {
    "tenantFilter": "contoso.com",
    "userId": "11111111-1111-1111-1111-111111111111",
    "top": 25
  }
}

userId may also be a UPN (alice@contoso.com). Omit top to use CIPP's default of 50.

Test plan

  • tests/cipp.service.signin-logs.test.ts — query name UserID, omitted top, explicit top, UPN resolution, unresolved UPN, allTenants, bad userId, out-of-range top, HTTP 500 surfaced, tool registration, handler dispatch
  • Full suite: 197 tests passed
  • Aaron: call against a real CIPP tenant and confirm the rows match the CIPP UI sign-in view for that user
Open in Web Open in Cursor 

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Wrap GET /api/ListUserSigninLogs, which Invoke-ListUserSigninLogs
implements by filtering Graph auditLogs/signIns on the Entra object id.
Send UserID (the query name the function reads), resolve a UPN first,
and reject allTenants and an out-of-range top before calling CIPP.

Co-authored-by: Aaron Sachs <asachs01@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Sep 23, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Comment @coderabbitai help to get the list of available commands.

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.

2 participants