AI Security
10 min read

AI Tool Identifiers: Same Shape, Different Target

Separate display names from executable identifiers, define Unicode comparison rules, and stop ambiguous text from selecting the wrong resource in AI workflows.

A cream-paper masquerade eye mask with aged-brass eyelets curls at one corner to reveal an oxblood lining on a walnut ledge.
AI Security / 10 min read
AIENGINE

10 min read

Share

An assistant can reproduce a document name exactly as it appears on screen and still select a different document. Two strings may look alike while containing different characters. Conversely, two differently encoded strings may represent the same text. A search box, model, database and approval screen can disagree about which distinction matters.

The engineering decision is which transformations may help find a resource, and which representation is allowed to identify the resource an AI tool will act on. Treating every string as a cleaned-up name leaves that decision implicit.

This field guide addresses text identity at tool boundaries, not model fluency or probabilistic record linkage. Primary standards, guidance and research establish the mechanisms; the proposed adapter contract and worked fixture are AIEngine's engineering analysis, not a claim of a tested customer deployment. Sources were checked on 17 September 2026.

Give each string a job

Separate four representations before writing a normalisation helper. The received value records what arrived. The display value helps a person read it. A comparison key supports a specified lookup rule. The resource identifier names the object accepted by the authoritative service.

Those representations may coincide for simple inputs, but that does not make them interchangeable. A document title can change without the document changing identity. Two documents can legitimately share a title. A search-friendly spelling can locate several candidates without authorising the application to pick one.

Preserve the received value when it is needed to explain a consequential decision, subject to the application's retention and access policy. Store transformation provenance alongside derived keys. Do not turn debugging into indefinite retention of every user message.

For actions, prefer an identifier returned by the source service and scoped to its tenant and resource type. If the upstream system only supports names, document its matching rules and obtain a current, unambiguous resolution before commitment. Calling an application-generated string an ID does not create upstream identity guarantees.

This distinction complements our entity-resolution guide. That article asks when records belong to one entity. Here the narrower question is whether a particular sequence of characters selects the intended object at all.

Normalisation answers only one equality question

Unicode's normalisation specification, UAX #15, distinguishes canonical equivalence from compatibility equivalence. NFC brings canonically equivalent sequences into a common composed form. NFKC additionally folds compatibility distinctions. The specification warns against applying compatibility normalisation indiscriminately because it can remove distinctions that matter.

For a small deterministic example, precomposed é and the sequence e followed by U+0301 COMBINING ACUTE ACCENT become equal under NFC. Fullwidth A and ordinary Latin A become equal under NFKC, but not NFC. Neither operation decides whether two source records should become one account.

Choose the rule per field and per protocol. A human-readable label may support normalised search. An opaque identifier, signed value or external resource key must follow its issuer's exact contract. Do not trim, case-fold or transliterate it merely because a shared text-cleaning function does so.

W3C's String Matching working draft of 16 July 2026 distinguishes case-sensitive, ASCII-insensitive and Unicode-insensitive comparisons, and discusses language-sensitive behaviour. It is work in progress, not a final W3C Recommendation. Its useful design lesson is to specify the equality operation instead of saying only “ignore case”.

A practical field specification should state the accepted encoding, permitted characters, length units, comparison transformation, case behaviour and collision response. Apply the same rules when creating and looking up application-owned names. For externally owned namespaces, adapt to the source contract instead of imposing a new identity scheme.

Detect resemblance without merging identities

Unicode's security mechanisms, UTS #39, provide confusable detection using derived skeletons. The standard explicitly says those skeletons are for internal comparison, not display or identifier normalisation. It also notes that confusable data can change between versions.

That makes a resemblance result a signal for investigation, not permission to substitute a target. Two names sharing a skeleton should not automatically share a database key, access decision or audit identity. Otherwise a control intended to detect ambiguity creates the collision itself.

Do not equate non-Latin text with malicious input. UTS #39 explains that joining controls can be necessary for normal appearance in some languages, and that blanket exclusion has usability costs. Restrictive rules suitable for a machine capability name need not be appropriate for a person's name or a document body.

For an application-owned privileged namespace, a deliberately small identifier alphabet may be reasonable. Keep friendly multilingual labels in separate fields. For imported names, retain the original and expose ambiguity through the resolver. Decide what happens when a name is permitted but resembles an existing high-consequence target.

Treat this as a product requirement as well as a validator rule. Users need a route to identify legitimate resources without learning code-point notation or accepting an accidental transliteration of their names.

Make the adapter bind a real target

The model can suggest a query or candidate, but the adapter should establish the binding between that suggestion and an executable command. A useful interface returns candidate resource IDs with distinguishing metadata, rather than asking the model to regenerate a name for the write step.

OWASP's input-validation guidance separates syntactic validation from semantic validation and requires server-side checking of fixed-choice values. It also explains why validation is not a replacement for context-aware output handling. Valid Unicode and valid JSON therefore remain insufficient evidence of an intended, permitted action.

A proposed adapter contract should make these obligations explicit:

  • Decode the declared transport encoding and reject malformed input for identifier fields.
  • Preserve the received identifier separately from any search-oriented transformation.
  • Apply a named, versioned comparison policy appropriate to that field's owner.
  • Return distinct candidates when several records satisfy the discovery rule.
  • Bind the selected candidate to its source-system ID, tenant and resource type.
  • Check the caller's current permission for that exact resource and operation.
  • Bind any required approval to the selected ID, relevant revision and proposed change.
  • Report the committed resource ID and reconcile it with the intended target.

There is no universal ordering in which every system should normalise and validate arbitrary text. A strict ASCII machine-ID contract can reject characters outside its alphabet immediately. A Unicode name profile may define normalisation before particular character checks. Implement the declared profile consistently and validate the value actually consumed downstream.

Do not let the model “repair” a rejected identifier and retry a consequential action without new resolution. A more familiar spelling can be a different target. Return a typed outcome such as ambiguous selection, unsupported representation or stale approval.

The wider output-validation framework covers structure, evidence, authority and safe destinations. Unicode-aware binding makes one of those boundaries precise; it does not replace the other gates.

Work through a deliberately ambiguous name

Consider a synthetic document-library fixture, not a reported incident. An assistant is asked to attach the approved annual report to a case. Two accessible records have similar-looking labels. Both contain plausible report material, but only the first is the approved publication.

The strings below are described with code points so the test does not depend on a reader noticing a font difference:

FixtureStored label constructionSource IDRequired behaviour
Approved documentLatin a, U+0061, followed by nnual-reportdoc_71Eligible only after approval evidence is checked
Different documentCyrillic a, U+0430, followed by nnual-reportdoc_94Keep distinct; do not silently substitute
Equivalent text encodingcafé using U+00E9 versus cafe followed by U+0301Separate test inputsNFC comparison agrees when the field contract specifies NFC
Compatibility variantFullwidth A, U+FF21, versus Latin A, U+0041Separate test inputsNFKC comparison agrees; exact and NFC comparison remain distinct

NFC and NFKC do not turn the Cyrillic letter in the second row into Latin a. A visual-similarity detector can flag the pair, but a normalisation call alone does not solve the selection problem.

Suppose the model chooses doc_94 and the user is allowed to read it. Authorisation correctly succeeds, yet the task is still wrong. The missing check is that the selected document has the required approval status and provenance. Access permission and intended identity are separate properties.

If the workflow already possesses the approved document's authoritative ID, carry it through to the attachment operation. If it has only a name and multiple plausible candidates, obtain the missing evidence or a disambiguating selection. Do not choose the first search result because its label looks right.

Finally, change the selected document after review. The test should show that approval for one revision cannot silently authorise a materially changed attachment. Our tool-contract versioning guide explains the related need to invalidate stale plans when the contract changes.

Make review screens tell the same truth

A human approval step is weak when the reviewer sees only a rendered label while the service executes a hidden identifier. Show the resource's source, type, stable ID and relevant status alongside its readable name. The confirmation must identify what the action will actually affect.

Boucher and Anderson's Trojan Source research, first submitted in 2021 and revised in 2023, demonstrates how encoded source code can present a different visual order from the logical order consumed by compilers. This is evidence about source-code interpretation, not a measured success rate against current language models. Applying the lesson to AI approval displays is an engineering inference.

Use a diagnostic view for suspicious identifiers: expose code points or escaped controls without rewriting the underlying resource value. Keep ordinary display usable, and make the diagnostic representation accessible through a clear explanation rather than a wall of unexplained hexadecimal numbers.

W3C's inline bidirectional-text guidance describes tightly wrapping inserted text and using direction-aware markup, including bdi or dir=auto when direction is unknown. Directional isolation helps prevent a label from disturbing neighbouring text. It does not prove that the label is genuine or make untrusted HTML safe.

Keep output encoding, text-direction handling and identity checks separate. Copying a readable label should not secretly copy a different executable command. If a control copies an ID, label that behaviour explicitly. Ensure that downloaded reports and operator logs preserve the same target binding as the approval interface.

Change comparison rules like a data migration

A comparison-policy update can alter which records a lookup returns even when no model or prompt changes. Before adopting it, compute proposed keys alongside existing keys and inspect newly introduced collisions, changed candidate sets and previously accepted inputs that would now fail.

Never resolve a collision by retaining whichever record is encountered first. Preserve the distinct source IDs and route the conflict according to the namespace's ownership rules. A uniqueness constraint on a derived key can detect a collision, but cannot decide which owner is entitled to the name.

Pin the implementation and relevant character-data versions in the resolver's release record. Where confusable skeletons are persisted, follow UTS #39's version-migration requirements; they are not stable interchange identifiers. Keep this issue distinct from the normalisation stability guarantees described in UAX #15.

The operational rollout should include a reversible index change, an inventory of consumers and a way to invalidate cached resolutions. Test old approvals and queued jobs explicitly. A stored display name should not be reinterpreted under a new comparison policy at execution time without detection.

If the new policy creates too many legitimate exceptions, investigate the field design and source contract. Broadening a regex until the queue clears can remove the very distinction the tool needs to preserve.

Measure target integrity, not blocked characters

Use a deterministic regression suite before involving the model. Assert exact resource IDs, comparison results, rejection reasons and committed targets. Include canonical-equivalence pairs, compatibility variants, cross-script lookalikes, legitimate joining controls, bidirectional formatting, duplicate labels, malformed transport and permission changes.

Then exercise the complete assistant with the same fixtures. Check whether retrieval preserves the original label, whether the model's candidate choice remains attached to its ID, and whether the adapter refuses an ambiguous or unsupported request. Repeat with the source content held constant while changing only the identifier representation.

Measure wrong-target proposals separately from wrong-target commits. Also track unresolved ambiguity, false rejection of legitimate names, review time, stale-approval failures and resolution changes after policy updates. A high count of blocked characters is not evidence that the system selects the right resources.

Include supported scripts in acceptance testing, using competent reviewers where interpretation is needed. The multilingual release guide offers the broader method for avoiding aggregate results that conceal a poorly served language population.

Revisit the boundary when a connector, database collation, parser, character-data library or review interface changes. The release claim should remain narrow and testable: discovery can be flexible, but the committed action stays bound to the intended, currently authorised resource.

TaggedUnicode SecurityAI Tool IdentifiersText NormalisationConfusable DetectionResource IdentityTool Validation
Work With Us

Interested in implementing this for your business?

We help UK businesses put these ideas into practice. Book a call to discuss your specific situation.