The Secure60 Microsoft 365 Connector is a lightweight container that collects
Microsoft 365 and Microsoft Entra ID (Azure AD) audit and identity telemetry and
sends it to Secure60 — either to your Secure60 Collector or directly to the Secure60
ingest endpoint. You deploy it in your own environment, and your Microsoft
credentials stay with you: they live in a local .env file and are never stored by
Secure60.
It collects from two Microsoft sources so you get both breadth and identity depth:
| Telemetry | Microsoft source | Licence required |
|---|---|---|
| Exchange, SharePoint, OneDrive, Teams, Entra and DLP audit activity | Office 365 Management Activity API | Unified Audit Logging enabled |
| Entra sign-in logs (interactive, non-interactive, service principal) | Microsoft Graph auditLogs/signIns |
Entra ID P1 or P2 |
| Entra directory audit (user / group / role / app changes) | Microsoft Graph auditLogs/directoryAudits |
Entra ID Free and above |
| Identity Protection risk detections and risky users | Microsoft Graph Identity Protection | Entra ID P2 |
A PowerShell script registers a single-tenant application, assigns the least-privilege permissions, grants admin consent, and creates a client secret — run it once as a Microsoft Global Administrator on a Windows machine with PowerShell.
Download the script:
Invoke-WebRequest -Uri https://www.secure60.io/docs/setup-s60-m365-connector-1.2.ps1 -OutFile setup-s60-m365-connector-1.2.ps1
Or download it from the direct link.
Run it (from the folder you downloaded it to):
Install-Module Microsoft.Graph -Scope CurrentUser # if not already installed
Unblock-File .\setup-s60-m365-connector-1.2.ps1 # clears the "downloaded file" warning
.\setup-s60-m365-connector-1.2.ps1 -TenantId your-tenant.onmicrosoft.com -WriteEnv
Pass your tenant with -TenantId (your onmicrosoft.com domain or the tenant GUID).
This matters if your admin account is a guest in the tenant or also exists as a
personal Microsoft account, so sign-in targets the right organization.
Where to find your Tenant ID: in the Microsoft Entra admin center
go to Identity → Overview — the Tenant ID (a GUID) and your primary
*.onmicrosoft.com domain are both shown there. Either value works for -TenantId.
If you get an execution-policy error, allow scripts for this session only:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned.
The default sign-in opens your browser. On a server with no browser you can add
-UseDeviceCode to sign in from another device — but note that many tenants
disable the device-code flow via Conditional Access, so where possible run the
script on a machine with a browser.
The script prints — and, with -WriteEnv, saves to .env — three values:
TENANT_ID, CLIENT_ID, and CLIENT_SECRET.
After setup, you can revoke the setup tool’s access. Registering the app uses Microsoft’s Microsoft Graph Command Line Tools application — this is only needed for the one-time registration, and you may get a Microsoft sign-in/consent notification for it. The connector runs on its own app registration (the
CLIENT_ID/secret above), so once setup is complete you can remove that tool’s access with no impact on the connector: Microsoft Entra admin center → Enterprise applications → “Microsoft Graph Command Line Tools” → remove (or, for a personal account, at account.microsoft.com under Privacy/Apps).
Prefer not to run the script? Follow the Manual Entra Setup guide to register the app and grant consent in the Entra admin center (or with the Azure CLI) instead — it produces exactly the same
TENANT_ID/CLIENT_ID/CLIENT_SECRET.
Create a .env file next to the connector with your Microsoft credentials and one
Secure60 destination:
# Microsoft app-only credentials (from Step 1)
TENANT_ID=00000000-0000-0000-0000-000000000000
CLIENT_ID=00000000-0000-0000-0000-000000000000
CLIENT_SECRET=your-client-secret
# Secure60 destination — choose ONE:
# Send to the Secure60 ingest endpoint:
PROJECT_ID=301
TOKEN=your-secure60-ingest-token
# …or send to your Secure60 Collector instead:
# S60_COLLECTOR_BASE=https://your-collector.internal
This is a complete configuration; every other setting has a sensible default.
Save this compose.yaml next to your .env (copy-paste as-is):
services:
s60-m365-connector:
image: "secure60/s60-m365-connector:latest"
container_name: "s60-m365-connector"
pull_policy: always
env_file:
- .env
volumes:
- s60-m365-state:/state
restart: always
volumes:
s60-m365-state:
Then start it:
docker compose up -d
docker compose logs -f
You should see authentication succeed and lines like
Forwarded 17 events -> ingest (HTTP 200). Events appear in your Secure60 project
within a few minutes.
Prefer no compose file? Run the image directly:
docker run -d --name s60-m365-connector --restart always \
--env-file .env -v s60-m365-state:/state \
secure60/s60-m365-connector:latest
A working configuration is just the Microsoft credentials plus one destination. Everything below is optional and shown with its default.
| Variable | Description | Default |
|---|---|---|
TENANT_ID |
Microsoft tenant (directory) ID | required |
CLIENT_ID |
App (client) ID of the registration | required |
CLIENT_SECRET |
App client secret | required |
PROJECT_ID |
Secure60 project ID (ingest mode) | — |
TOKEN |
Secure60 ingest token (ingest mode) | — |
S60_COLLECTOR_BASE |
Secure60 Collector URL (collector mode) | — |
S60_INGEST_BASE |
Secure60 ingest base URL | https://ingest.secure60.io |
ENABLE_MGMT_ACTIVITY |
Collect the Management Activity audit feed | true |
ENABLE_GRAPH |
Collect Microsoft Graph feeds | true |
MGMT_CONTENT_TYPES |
Management Activity content types to subscribe to | all core types |
POLLING_INTERVAL_MINUTES |
How often to poll | 5 |
INITIAL_LOOKBACK_MINUTES |
History to fetch on first run | 1440 |
HEARTBEAT_INTERVAL_MINUTES |
How often to emit a health heartbeat | 15 |
MS_LOGIN_BASE / MS_MANAGE_BASE / MS_GRAPH_BASE |
Microsoft cloud endpoints (override for GCC / GCC High / DoD) | commercial cloud |
LOG_LEVEL |
INFO or DEBUG |
INFO |
The destination mode is inferred automatically: set PROJECT_ID + TOKEN for
ingest, or S60_COLLECTOR_BASE for your collector.
Events are sent as flat JSON aligned with the Secure60 CIM. Every event carries
vendor, product, app_name=ms365, technology_group=windows, plus normalized
fields and the original Microsoft fields (prefixed event_). The type field
reflects the entity an event targets — email (Exchange), file (SharePoint /
OneDrive) or user (Entra sign-ins and directory changes).
Common fields:
operation — the normalized activity, e.g. user-login,
active-directory-modify, azure-app-create, email-service-modify,
user-permission-modify.outcome — success or failure.user_name — the acting user (UPN).ip_src_address — the source IP address (geo-enriched on arrival).timestamp — the time the activity occurred at the source.event_* — the full Microsoft record, flattened. Nested key/value details
become discrete fields you can match on directly, for example
event_additionaldetails_user_agent or event_targetresources_0_displayname.Because the data is normalized to CIM, you can correlate Microsoft 365 activity with other sources and write Rules against these fields immediately.
.env before it lapses — an
expired secret silently stops collection.secure60/s60-m365-connector:1.1) for
reproducible deployments, and upgrade deliberately.For help deploying the Secure60 Microsoft 365 Connector, contact the integrations team at integrations@secure60.io.