DFINITY IT, in one place.
Devices, licenses, people and support tickets run on the DFINITY cloud engine. Every change is written to a tamper-evident, hash-chained audit log on the canister. Sign in with Internet Identity — IT works the full tool, everyone else gets their personal portal.
Almost there.
Your sign-in works, but this identity is not connected yet. Got an invite code from IT? Redeem it here:
No code? Ask IT to connect you — this files a ticket with your identifier automatically:
Your identifier:
This device is company property.
Found it? Please contact it@dfinity.org.
| ID | SUBJECT | CUSTOMER | CATEGORY | PRIORITY | STATUS | ASSIGNEE | UPDATED |
|---|
| № | NAME | SCOPE | STARTED | STATUS | SCANNED | DEFECTIVE |
|---|
| VENDOR | PRODUCT | LICENSE | SEATS | COST | RENEWAL | IN | AUTO |
|---|
SaaS contracts live alongside your hardware. Add one and paste the contract (or upload a PDF) — the AI pre-fills vendor, license, renewal date, notice period and contacts for you to confirm. Renewal countdowns turn amber inside the notice window. (Slack renewal alerts are the next step.)
| NAME | SOURCE | NOTE | CHECKED OUT | PORTAL |
|---|
Roster people come from the company directory (lunch-checkin canister) and are read-only here — manual people can be opened, edited, deactivated, or removed. Portal: link a person's Internet Identity directly (paste their principal), or mint a one-time invite code and DM it to them — they redeem it on the sign-in screen and get their personal dashboard (their devices, licenses, and tickets).
One workspace, one dataset. The v14 collapse removed multi-company support — assets, people, contracts, tickets and the audit chain all belong to this workspace.
| NAME | ASSETS | MODELS |
|---|
| NAME | NOTES | ASSETS |
|---|
Filtering happens on the canister: attributes you hide are never sent to anonymous callers, not just hidden in the browser. Serial numbers, owners, and costs are never public regardless of these settings. Any admin may change this; every change is recorded in the audit log.
The token is stored write-only on the canister: no method returns it, the GUI only ever shows a fingerprint — use a read-only Kandji token scoped to the device list, and rotate it occasionally. Saving and the auto-sync toggle are owner-only. Sync matches on serial number: known devices get their MDM facts (last check-in, OS, user) attached and empty hardware fields filled; unknown devices become new assets (assigned to the Kandji user when known); active Apple assets Kandji doesn't know are reported as drift. The registry stays the owner of tags, lifecycle, and everything it already knows. Models are registered automatically from Kandji's marketing names, and each sync additionally pulls a few devices' hardware details to fill missing model numbers (identifiers like "Mac15,7") — a handful per run, so the whole fleet fills in over a few syncs. Every sync is recorded in the audit chain. Calls are single-node (non-replicated) HTTPS outcalls — the right mode for a non-deterministic API on our own engine.
Used only for contract field extraction (Contracts → Analyze with AI). Contract text is sent to this endpoint, so point it at the suite's Intelligence Gateway or a provider with an acceptable data agreement — it's your text leaving the engine. Key stored write-only (fingerprint-only), owner-only, single-node outcall. Choose OpenAI-compatible (OpenAI, OpenRouter, gateways) or Anthropic (Claude).
Your IdP pushes user lifecycle events here (create, update, deactivate, delete) — standard SCIM 2.0, so Okta, Entra and others all work. Existing people are linked by email instead of duplicated. Offboarding never touches checked-out assets: the device stays checked out to the departed person and gets a "departed" event in the audit chain, so you can see what to reclaim. Once SCIM is enabled for this company, the shared lunch-checkin roster disappears from People and checkout autocomplete — the IdP is then the source of truth.
Step-by-step: connect Okta
- Set the token here first. Generate a long random secret (e.g.
openssl rand -hex 32), paste it above, tick SCIM enabled, hit Save SCIM. Okta's test fails with 401/403 until this is done. - In Okta Admin: Applications → Applications → Create App Integration → SAML 2.0. (The SAML app is only a carrier for SCIM — sign-in to this registry stays Internet Identity.)
- General Settings: App name e.g.
Asset Registry SCIM; App visibility: tick "Do not display application icon to users". - Configure SAML (placeholder values, never used): Single sign-on URL = this app's URL; Audience URI =
asset-registry; Name ID format = EmailAddress; Application username = Email (this one matters — SCIM matches people by email); Update application username on = Create and update. - Feedback: "This is an internal app that we have created" → Finish.
- In the new app: General → App Settings → Edit → Provisioning: SCIM → Save. A Provisioning tab appears.
- Provisioning → Integration → Edit: SCIM connector base URL = the Base URL above; Unique identifier field for users =
userName; Supported provisioning actions: Push New Users + Push Profile Updates only (no Import, no Groups); Authentication Mode = HTTP Header → paste the same bearer token → Test Connector Configuration (a few seconds — the calls run through chain consensus) → Save. - Provisioning → To App → Edit: enable Create Users, Update User Attributes, Deactivate Users → Save. Skipping this causes "Matching user not found" on assignment.
- Assignments → Assign the people or groups that belong in this company's registry. Each push shows up in the status line above; people appear under Settings → People with a
scimpill. - Offboarding test: unassign a test user in Okta → they turn inactive here; any device still checked out to them gets a red departed badge + an audit-chain event.
- Troubleshooting: "Matching user not found" → step 8 not done; stuck users retry under Okta Dashboard → Tasks (or unassign/re-assign). 401 in the status line above → token mismatch between Okta and this page.
A daily check posts to Slack when a contract is inside its notice window (its own notice period, or the default lead time above when none is set), then repeats every "remind every" days until the contract is renewed or cancelled — all due contracts batched into one message. Webhook stored write-only (fingerprint-only), owner-set. Create the webhook in Slack → Apps → Incoming Webhooks, pick the channel there. Single-node outcall, same pattern as Kandji.
Step-by-step: create the Slack app
- Create the app from a manifest:
api.slack.com/apps→ Create New App → From a manifest → pick the DFINITY workspace → paste the JSON below → Create. - Install: Settings → Install App → Install to Workspace. Copy the Bot User OAuth Token (
xoxb-…) into BOT TOKEN above. - Signing secret: Basic Information → App Credentials → Signing Secret → paste into SIGNING SECRET above → Save Slack. (The endpoint rejects unsigned requests, so save BEFORE the next step.)
- Verify the events URL: Features → Event Subscriptions → the Request URL (prefilled from the manifest) should show Verified. If it timed out earlier, hit Retry — the canister answers the challenge through chain consensus, which can take a couple of seconds.
- Invite the bot FIRST — in Slack, open the support channel (e.g. #help-it) and run
/invite @IT Super Tool. The picker below only lists channels the bot is a member of, so without the invite the list stays empty. Private channels are invisible to the bot until invited, by Slack design. - Back here: Load channels → your channel appears in the dropdown → pick it → tick Intake enabled → Save Slack → Test connection.
- End-to-end test: post a message in the channel as a normal user → the bot answers in the thread with the ticket number + AI summary within a few seconds; your reply from the Tickets view lands back in the thread under your agent name.
- Troubleshooting: "bad signature" in the status line → signing secret mismatch. Bot silent → is it invited to the channel, and is Intake enabled? Replies post as the plain bot instead of your name → the
chat:write.customizescope is missing (re-install the app).
Employees post in the support channel and never leave Slack: Slack PUSHES every message to this canister (Events API — no polling), the AI triage (Settings → Integrations → AI) pre-fills subject, category, priority and a short summary, the customer is matched to People by their Slack e-mail, and the bot acknowledges in the thread with the ticket number. Thread replies sync back instantly and reopen resolved tickets; replies from the Tickets view land in the thread under the agent's name; internal notes never leave the canister. Every inbound event is signature-verified (HMAC over the signing secret) and deduplicated.
| PRINCIPAL | NAME | ROLE |
|---|
Owners manage access here. Every admin is also a ticket agent. The first registered admin became the owner automatically. The last owner cannot be demoted, and an owner must be demoted before removal. The CLI controller identity keeps working as break-glass. Display names show up in ticket assignment, Slack replies and the audit trail. Every change lands in the audit log.
| ID | SUBJECT | CATEGORY | STATUS | UPDATED |
|---|
| TAG | NAME | MODEL | SERIAL | STATUS | WARRANTY |
|---|
| VENDOR | PRODUCT | LICENSE |
|---|
Something missing or wrong? Open a request above, or write in #help-it on Slack — both land in the same IT queue.