How to

How to build an IT asset and licence tracker

Somebody left in March and their laptop is still assigned to them in a spreadsheet last edited in January. Here is the model behind a tracker, the prompts to build it, and what it takes to run it.

The short answer

An IT asset and licence tracker needs four things: an asset record with a lifecycle state, an assignment history rather than a current-holder field, licences modelled separately from devices, and a reconciliation against what your management systems actually see. The reason spreadsheets fail here is the assignment field: overwriting it destroys the history, so nobody can answer who had this device in June, which is the question that gets asked during an incident.

assets.helix-app.ai

Assets and licences

412

Assets tracked

38

Seen but not registered

312K

Unassigned licence value

2

Held by people who left

Asset Serial State Held by Since
MacBook Pro 14 C02XK1 Assigned A. Mensah 14 Mar 2026
MacBook Air 13 C02YT9 In repair - 2 Sep 2026
Dell U2723 CN4471 Assigned S. Roche 8 Jan 2026
MacBook Pro 16 C02QP4 Assigned J. Ortiz (left) 3 Nov 2025
iPhone 15 F17KL2 In stock - 21 Aug 2026
A sketch of the register. The holder column is a history, not a field: overwriting it deletes the answer to who had this device in June, which is the question an incident asks.

What matters here

  • An asset tracker is four parts: assets with a lifecycle, an assignment history, licences modelled separately, and reconciliation against reality.
  • Store assignments as history, not as a current-holder field. Overwriting deletes the answer to who had this device in June.
  • Licences are not devices. They attach to people, renew on dates, and can be reclaimed, so they need their own model.
  • Reconcile against your device management and identity systems. A tracker that only knows what people typed into it drifts within a quarter.
  • Lifecycle states matter more than location. In stock, assigned, in repair, retired and disposed each mean something different for cost and for risk.
  • Asset data feeds security incidents and audits, so scoped access and managed credentials belong in the build.

Who this is for

You run IT or operations. You already have a spreadsheet. What you want is to know where every device is, who has had it, what licences you are paying for, and to have that survive contact with a leaver.

How it works in practice

What the register does that a spreadsheet cannot, in the order you would use it.

  1. 1

    Every device has a lifecycle state, not a location

    Ordered, in stock, assigned, in repair, lost, retired, disposed. State drives cost and risk reporting differently.

  2. 2

    Assignments are rows, never a field

    Assigning opens a row, returning closes it, and the full chain of custody survives.

  3. 3

    The recipient confirms receipt

    So the record says the device arrived rather than that somebody meant to send it.

  4. 4

    Licences get the same treatment

    Seats bought, seats assigned, last used, and the annual value of what nobody is touching.

  5. 5

    Reality gets checked against the register

    Imports from device management and your identity provider produce three lists, and the third one grows on its own.

  6. 6

    The audit export is one click

    Every asset, its state, its holder and its full history for a period.

What an asset tracker is made of

An asset tracker is not an inventory list. It is four parts, and the second is the one a spreadsheet cannot do.

Assets with a lifecycle

Each device with a type, identifiers, purchase details, warranty, and a lifecycle state. State drives cost reporting and risk reporting differently, so it cannot be a free-text location field.

An assignment history

Every assignment as a row with a from and to date, not a field on the asset. Current holder is derived from the open row.

Licences

Software entitlements with their own records: total seats, assignments, renewal dates and cost per seat. Related to people, not to hardware.

Reconciliation

A comparison against what device management and identity systems actually report, producing three lists: known and seen, known and unseen, and seen but unknown.

These prompts start from a Helix project, which is what handles sign-in, credentials and hosting. Start with Helix

The prompts

Paste these into Claude Code, Codex or Cursor in order. Each one leaves you with something that runs, so you can stop after any step.

  1. Assets with a state that means something

    Not a free-text location field.

    In this Helix project, build me an IT asset and licence tracker.
    
    Assets first: asset tag, type, make, model, serial number, purchase date
    and cost, supplier, warranty expiry, expected replacement date, condition,
    location, and a lifecycle state.
    
    Make the state a fixed list, not free text: ordered, in stock, assigned,
    in repair, lost, retired, disposed. Record every state change with a
    timestamp, who changed it and why. Lifecycle drives both cost reporting
    and risk reporting, and it cannot be a location field with words in it.
    
    Derive depreciation from the purchase cost and a schedule I configure per
    asset type, and show the current book value. Flag anything past its
    expected replacement date, and anything with warranty expiring in the next
    90 days.
    
    Import from CSV with the column mapping in one editable file.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
  2. Assignment as history

    The thing spreadsheets get wrong, and the reason to build this.

    Now assignment, and do not put a current-holder field on the asset.
    
    Instead, assignment is a row: asset, person, assigned at, assigned by,
    returned at, returned condition, notes. The current holder is derived from
    the row that has no return date. Returning closes a row, assigning opens a
    new one, and the full history stays intact.
    
    Overwriting a holder field deletes the answer to who had this device in
    June, which is precisely the question a security investigation asks.
    
    Give me a view per person of everything currently assigned and everything
    they have ever held, and a view per asset of the whole chain of custody.
    
    Add an acceptance step: when an asset is assigned, the recipient confirms
    receipt and condition, and that confirmation is recorded.
    
    And if I give you a list of current staff, flag any asset assigned to
    somebody no longer active. That list should be empty and it rarely is.

    Worth knowing. Chain of custody is the reason to build this rather than maintain a spreadsheet, and nobody misses it until a device with customer data goes missing.

  3. Licences, which cost more and get tracked less

    Same history model, different object.

    Licences get their own records: vendor, product, licence type, total seats,
    cost per seat, annual cost, term start and end, auto renew, notice period,
    contract reference and owner.
    
    Assignments use the same history model as assets, for the same reason,
    plus a last-used date per person.
    
    Derive seats used, seats free, and the annual value of unassigned seats.
    Then a reclaim list: assignments where last used is older than a threshold
    I set, ranked by what reclaiming them is worth.
    
    Sort the renewal view by notice deadline, which is term end minus notice
    period, rather than by term end. Sorting by term end shows me contracts I
    can no longer cancel.
    
    And flag licences assigned to inactive people, which is a cost problem and
    an access problem at the same time.
  4. Check the register against reality

    The reconciliation that finds what nobody recorded.

    Import a device list from device management and a user list from the
    identity provider, on a schedule.
    
    Produce three lists. Assets we know about and management can see. Assets
    we know about that have not been seen for longer than a threshold. And
    devices management can see that are not in the register at all.
    
    That third list is the one that grows on its own, and it is exactly what a
    manual inventory cannot find.
    
    Match on serial number first, then asset tag, then hostname. Show the last
    successful import time on every page, and say so clearly when an import
    fails rather than serving stale data quietly.
    
    Then reporting: asset count and value by type, state and location;
    replacement spend by quarter; average age of assigned devices; unassigned
    licence value; and everything held by people who have left. Plus an audit
    export of every asset with its full assignment history for a period.
  5. Connect it to real systems

    The step that turns a working prototype into something with your data in it.

    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Jamf>. Read every device it can see, which produces the list of hardware
    nobody registered.
    
    <Okta>. Read current staff, so assets and licences held by leavers surface
    immediately.
    
    <each vendor admin API>. Read assigned seats per tool, which is how you
    find licences still allocated to people who left.
    
    <NetSuite>. Read the purchase record and the capitalised value, so the
    register agrees with what finance has on the balance sheet.
    
    <Intune>. Read Windows devices, since most estates are not one platform
    whatever the standard says.
    
    <Coupa>. Read purchase records and warranty terms rather than retyping
    them.
    
    <Slack>. Ask somebody to confirm they still have a device the register has
    not seen for a while.
    
    <Snowflake>. Keep a dated snapshot of the register, so what we owned and
    paid for last March is answerable and not just what is true today.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.

    Worth knowing. Every name in angle brackets is a placeholder for whatever you run. Helix holds the credential as a workspace authentication, so the app references an alias and never the secret itself.

  6. Ship it

    The last step of every build: a URL, and the right people on it.

    Deploy my app.

    Worth knowing. Your assistant runs helix deploy underneath and the app comes back as a URL. This register says who holds what and feeds security investigations, so set Access Control before sharing: managers see their team, IT sees the estate.

What it connects to

A register that only knows what people typed into it drifts within a quarter. Reconciliation is the fix.

  • Jamf

    Read every device it can see, which produces the list of hardware nobody registered.

  • Okta

    Read current staff, so assets and licences held by leavers surface immediately.

  • Each vendor admin API

    Read assigned seats per tool, which is how you find licences still allocated to people who left.

  • NetSuite

    Read the purchase record and the capitalised value, so the register agrees with what finance has on the balance sheet.

  • Intune

    Read Windows devices, since most estates are not one platform whatever the standard says.

  • Coupa

    Read purchase records and warranty terms rather than retyping them.

  • Slack

    Ask somebody to confirm they still have a device the register has not seen for a while.

  • Snowflake

    Keep a dated snapshot of the register, so what we owned and paid for last March is answerable and not just what is true today.

Each line says whether the app reads, writes or both. Anything not described as writing should be read only.

Named systems are the ones most teams actually run, not a list of the only ones that work. Swap in whatever you use.

Each connection is an authentication in your Helix workspace, referenced by alias. The app names the connection it wants and never holds the credential, so nothing here ends up in your code and any of it can be rotated or revoked without a redeploy.

Running it for real

The build gets you a working tracker. It reads from device management and identity systems and feeds security investigations, so how it is run matters as much as what it stores.

AI Deployment

Get it to a URL people can open

One command takes the app from your assistant to a live address, so the people who need it get a link rather than instructions for running it locally.

App Security

Put your identity provider in front of it

Asset and licence records identify who holds what. SSO means people sign in with their existing account, and access is scoped so a manager sees their team while IT sees the estate.

App Security

Connect the system of record with managed credentials

Importing device and user lists on a schedule needs real access to those systems. Granting it to the app rather than pasting keys into it means credentials can be rotated or revoked without a redeploy.

App Registry

Put a name on it

Every app carries a named owner and an entry IT can see, so the tool does not become nobody's problem when the person who built it changes role.

Cost Management

Know what it costs to run

Per-app spend visibility, with budgets and caps, so an internal tool cannot quietly become a line item nobody can explain.

Questions people ask

What should an IT asset tracker record?

Each device with identifiers, purchase and warranty details, a lifecycle state from a fixed list, and a full assignment history rather than a single current-holder field. Licences need their own records with seats, renewal dates and usage.

Why store assignment history instead of a current holder?

Because overwriting the holder deletes the answer to who had this device in June, which is the question asked during a security investigation. Storing assignments as rows with from and to dates keeps the chain of custody intact.

How do I stop an asset tracker going stale?

Reconcile it against what your device management and identity systems actually report, on a schedule. A tracker that only knows what people typed into it drifts within a quarter, and the drift is invisible until you need it.

What is the most useful reconciliation output?

The list of devices seen by management but absent from the tracker. Devices nobody recorded are exactly what a manual inventory cannot find, and that list tends to keep producing results long after the others go quiet.

How should software licences be modelled?

Separately from hardware, with total seats, per-seat cost, assignment history, last-used dates and a renewal date derived from the notice period. The reclaim list of unused seats is usually where the money is.

Can I build this without an engineering team?

Yes. The prompts here are written for Claude Code, Codex or Cursor and stage the build from a CSV import. The judgement calls are your lifecycle states and your inactivity threshold for reclaiming licences.

Last reviewed September 2026.

Build it, then run it properly

Helix is the governed runtime for AI-built apps. Deploy what you build, put SSO in front of it, connect it to your systems with managed credentials, and give it a named owner.