Identity & Metadata
The SDK lets you pass user identity and freeform metadata with every MCP request. Igris uses this for:
- Policy evaluation — rules can match on
user or metadata.role, metadata.team, etc.
- Audit trail — every event shows who made the request
- Trace correlation — group multiple tool calls from the same user request
Passing Identity
const config = igris.getMcpConfig("vk_github_prod", {
user: "alice@company.com",
traceId: "req_abc123",
metadata: {
role: "developer",
team: "engineering",
environment: "production",
},
});
All fields are optional. If you don’t pass them, the gateway still works — just without identity-based policies or user-level audit.
How It Works
The SDK translates these into HTTP headers:
| SDK Parameter | HTTP Header | Purpose |
|---|
user | X-Igris-User | End-user identity (opaque string) |
traceId | X-Igris-Trace-Id | Cross-call correlation |
metadata | X-Igris-Metadata | JSON key-value pairs for policy matching |
Trace IDs
Trace IDs let you group multiple tool calls from a single user request.
const traceId = "req_abc123"; // your request ID
// All three calls share the same trace
const githubConfig = igris.getMcpConfig("vk_github", { traceId, user: "alice" });
const slackConfig = igris.getMcpConfig("vk_slack", { traceId, user: "alice" });
const notionConfig = igris.getMcpConfig("vk_notion", { traceId, user: "alice" });
In the audit trail, filter by traceId to see the complete chain.
Auto-generation: If you don’t pass a traceId, the SDK generates one automatically (ig_trace_ + random hex). Each getMcpConfig() call gets its own trace ID.
Metadata enables attribute-based access control. Pass any key-value pairs:
metadata: {
role: "developer",
team: "engineering",
environment: "production",
customerId: "cust_456",
}
Then create policies that match on these fields:
{
"rules": [
{ "tool": "delete_*", "action": "deny", "conditions": { "metadata.role": "intern" } },
{ "tool": "*", "action": "allow" }
]
}
Condition Operators
| Operator | Example | Meaning |
|---|
| String (shorthand) | "metadata.role": "intern" | Equals “intern” |
eq | "metadata.role": { "eq": "intern" } | Equals “intern” |
neq | "metadata.role": { "neq": "admin" } | Not equals “admin” |
in | "metadata.role": { "in": ["dev", "admin"] } | Value in list |
nin | "metadata.role": { "nin": ["intern"] } | Value not in list |
Missing Fields
If a policy rule has a condition on metadata.role but the request doesn’t include metadata (or the role field is missing), the rule is skipped — not denied. This follows standard ABAC behavior.
User-based policies are advisory, not security boundaries. Any holder of an API key can set any X-Igris-User value. The API key is the real trust anchor. For per-user security, use separate API keys per user/team.
| Constraint | Limit |
|---|
| Max size | 4 KB |
| Max nesting | 3 levels |
| Key format | No dots in key names (dots used for field resolution) |
| Invalid JSON | Header ignored (treated as absent) |