Self-hosted processor
The self-hosted processor keeps AI Code Insights session transcripts inside your network. Developer laptops send sessions to a processor that you run instead of to DX. The processor stores transcripts on its own volume, runs session summaries, work type assignment, and evaluations with your Amazon Bedrock account, and sends DX only session metadata and analysis results, never titles or message content.
Only session uploads change destination. Commits, settings, updates, and all other daemon traffic continue to go to DX. DX never connects to the processor; the processor calls DX.
Note: The processor requires AI Code Insights daemon 0.7.8 or later. DX turns on processor mode for your organization.
Before you begin
- Daemon 0.7.8 or later on every developer laptop, or a plan to get there with automatic updates.
- A Linux container platform, such as Kubernetes or Amazon ECS, that can run one container with a persistent local volume.
- An internal hostname and TLS certificate for the processor. A certificate from your organization’s own certificate authority works when developer laptops trust that authority.
- Network access from every developer laptop to that hostname, through your corporate network, VPN, or zero-trust access proxy.
- Amazon Bedrock access in an AWS account you control. See Step 2: Deploy the processor for the required models and permission.
- A DX web API token for the processor’s connection to DX. This is not the AI Code Insights organization token.
- Endpoint management that can deliver one more setting to laptops: MDM on macOS and Windows, and configuration management on Linux.
Step 1: Upgrade daemons
Open Admin → AI Code Insights → Client versions and confirm that active developers run 0.7.8 or later. Turn on automatic updates to move the remaining endpoints forward.
Daemons older than 0.7.8 do not route sessions to the processor. After processor mode is on, they keep uploading sessions to DX, and DX discards their titles and message content. Those sessions are not summarized or evaluated. Upgrade them before Step 5: Turn on processor mode.
Step 2: Deploy the processor
The processor is published as a public image for linux/amd64 and linux/arm64:
ghcr.io/get-dx/daemon-processor:v0.2.0
Pin a release tag, or its digest from the package page, rather than a moving reference.
The container runs as UID and GID 65532 and serves plain HTTP on port 8080. GET /healthz returns ok while the process is up. It does not report DX connectivity or analysis progress. The processor shuts down within 10 seconds of SIGTERM; allow a longer grace period.
Environment variables
| Variable | Required | Description |
|---|---|---|
DATACLOUD_URL |
Yes | Your DX instance URL, for example https://yourinstance.getdx.net. |
DATACLOUD_KEY |
Yes | The DX web API token. Pass it from a secret store. |
AWS_REGION |
Yes | The Bedrock region, for example us-east-1. |
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY |
No | Only when the processor has no IAM role, for example outside AWS. |
RETENTION_DAYS |
No | Maximum age of stored content, from 1 to 365 days, measured from when the content was produced. Defaults to 7. |
LISTEN_ADDR |
No | HTTP listen address. Defaults to :8080. |
The processor exits at startup, naming the missing variables, unless all required variables are set.
On Amazon ECS, EKS, or EC2, give the processor an IAM role (an ECS task role, IAM roles for service accounts or Pod Identity, or an instance profile) and leave the AWS keys unset. The processor calls openai.gpt-5.6-luna and anthropic.claude-haiku-4-5-20251001-v1:0 through cross-Region inference profiles: the geographic profile for your Region, such as us., or the global. profile where none exists. In EU, Japan, and Australia Regions, summaries use Claude Haiku so that transcripts stay in the geography. Enable access to both models in your account.
Granting access to the inference profiles alone is not enough. Amazon Bedrock also authorizes the underlying model in every Region a profile can route to, the Region-less model for global. profiles, and, for GPT-5.6 Luna, your account’s default Bedrock project. This policy covers all of them for any Region. Replace ACCOUNT_ID with your AWS account ID:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "InferenceProfiles",
"Effect": "Allow",
"Action": "bedrock:InvokeModel",
"Resource": [
"arn:aws:bedrock:*:ACCOUNT_ID:inference-profile/*.openai.gpt-5.6-luna",
"arn:aws:bedrock:*:ACCOUNT_ID:inference-profile/*.anthropic.claude-haiku-4-5-20251001-v1:0"
]
},
{
"Sid": "ModelsThroughInferenceProfiles",
"Effect": "Allow",
"Action": "bedrock:InvokeModel",
"Resource": [
"arn:aws:bedrock:*::foundation-model/openai.gpt-5.6-luna",
"arn:aws:bedrock:*::foundation-model/anthropic.claude-haiku-4-5-20251001-v1:0",
"arn:aws:bedrock:::foundation-model/openai.gpt-5.6-luna",
"arn:aws:bedrock:::foundation-model/anthropic.claude-haiku-4-5-20251001-v1:0"
],
"Condition": {
"StringLike": {
"bedrock:InferenceProfileArn": "arn:aws:bedrock:*:ACCOUNT_ID:inference-profile/*"
}
}
},
{
"Sid": "LunaDefaultProject",
"Effect": "Allow",
"Action": "bedrock:InvokeModel",
"Resource": "arn:aws:bedrock:*:ACCOUNT_ID:project/default"
}
]
}
If service control policies in your organization block Regions, they must allow the destination Regions of your Region’s profiles. See geographic and global cross-Region inference for the requirements.
The processor does not check credentials at startup. Missing credentials, denied access, or an unavailable model pause analysis and log processor analysis paused with the AWS error code until you fix them. These errors never cause the processor to give up on a session, but retention still deletes content older than RETENTION_DAYS, so a misconfigured role loses those sessions’ analyses. After deploying, end a test session on a routed laptop and confirm that the processor logs processor analysis reported within a few minutes.
Storage and replicas
On Kubernetes, use a StatefulSet, or a Deployment with replicas: 1 and the Recreate strategy, never a rolling update.
Give the processor a persistent volume. It holds the only copy of each transcript until the transcript is analyzed, because laptops delete a session from their local queue once the processor stores it. Without a persistent volume, every restart loses the sessions waiting for analysis.
The processor stores sessions in SQLite, which needs a local or block-storage volume, not a network file system such as NFS or EFS. With Docker, mount a named volume at /data. On Kubernetes, follow the example below, which handles the volume’s permissions.
The processor deletes content older than RETENTION_DAYS at startup and hourly. Deletion removes database rows; it does not securely erase disk pages or volume snapshots.
Example Kubernetes deployment
Adapt this example to your cluster. It assumes the ingress-nginx controller with an ingress class that is reachable only from your network, an existing TLS secret, and a service account bound to an IAM role with Bedrock access.
kubectl create secret generic daemon-processor \
--from-literal=datacloud-key="$DX_WEB_API_TOKEN"
apiVersion: v1
kind: Service
metadata:
name: daemon-processor
spec:
selector:
app: daemon-processor
ports:
- name: http
port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: daemon-processor
spec:
serviceName: daemon-processor
replicas: 1 # Never run more than one.
selector:
matchLabels:
app: daemon-processor
template:
metadata:
labels:
app: daemon-processor
spec:
serviceAccountName: daemon-processor # Bound to an IAM role with Bedrock access.
terminationGracePeriodSeconds: 30
securityContext:
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532 # Lets the processor write to the new volume.
containers:
- name: daemon-processor
image: ghcr.io/get-dx/daemon-processor:v0.2.0
ports:
- name: http
containerPort: 8080
env:
- name: DATA_DIR # The volume's root is not private, so store in a subdirectory.
value: /var/lib/daemon-processor/data
- name: DATACLOUD_URL
value: https://yourinstance.getdx.net
- name: DATACLOUD_KEY
valueFrom:
secretKeyRef:
name: daemon-processor
key: datacloud-key
- name: AWS_REGION
value: us-east-1
livenessProbe:
httpGet:
path: /healthz
port: http
volumeMounts:
- name: data
mountPath: /var/lib/daemon-processor
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi # Size for RETENTION_DAYS of your organization's sessions.
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: daemon-processor
annotations:
# Laptops send request bodies of up to 2 MiB; ingress-nginx allows 1 MiB by default.
nginx.ingress.kubernetes.io/proxy-body-size: "32m"
spec:
ingressClassName: internal-nginx # Reachable only from your network.
tls:
- hosts:
- ai-processor.internal.example.com
secretName: daemon-processor-tls
rules:
- host: ai-processor.internal.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: daemon-processor
port:
name: http
Step 3: Expose the processor to developer laptops
Every developer laptop connects to the processor, so the processor needs inbound access from your developer network, unlike the daemon’s outbound-only connections to DX. Before you configure laptops, confirm each item:
- Internal only. The upload endpoint does not authenticate uploaders. Anyone who can reach it can submit sessions under any developer identity. Never expose it to the internet.
- HTTPS at the ingress or load balancer, forwarding plain HTTP to port
8080. The daemon uses the operating system’s trusted certificates, so a certificate from your organization’s certificate authority works on laptops that trust it. - The processor at the root of its hostname.
processor_urlis an origin, such ashttps://ai-processor.internal.example.com, and cannot include a path, so the processor cannot share a hostname under a path prefix. - Request bodies of at least 2 MiB through every proxy and load balancer. A proxy that rejects a body with HTTP
413causes the laptop to discard that part of the session. - Reachable on every network path developers use: office, VPN, and remote access.
- Outbound access from the processor to your DX instance URL and to Amazon Bedrock in
AWS_REGION.
From a developer laptop, confirm that DNS, TLS, and routing work:
curl https://ai-processor.internal.example.com/healthz
The command prints ok. Repeat it from each network path.
Laptops that cannot reach the processor keep sessions in a local queue and retry. They never fall back to uploading transcripts to DX. The processor does not store content that is already older than RETENTION_DAYS when it arrives, so a laptop that stays off the network for longer than that loses analysis for its older sessions.
Step 4: Configure laptops
Deliver processor_url through the same channel as your other AI Code Insights settings. Managed values on macOS and Windows take priority over the config file unless the developer sets prefer_local_config.
Add the key to the com.getdx.aicodemetrics payload of your Configuration Profile:
<key>processor_url</key>
<string>https://ai-processor.internal.example.com</string>
Deliver processor_url as REG_SZ under HKLM\SOFTWARE\GetDX\AICodeMetrics.
Add processor_url to ~/.aicodemetrics/config.json:
{
"api_url": "API_URL",
"api_key": "API_TOKEN",
"email": "developer@example.com",
"processor_url": "https://ai-processor.internal.example.com"
}
The value must be an HTTPS origin with no path, query, or fragment. Daemon 0.7.7 and later stop monitoring while processor_url is invalid and log Waiting for valid URL configuration. Deliver it to a few laptops and check them before rolling it out widely.
Delivering processor_url is safe before processor mode is on. Until then, daemons 0.7.8 and later keep uploading sessions to DX, and older daemons ignore the setting.
The daemon reads processor_url at startup. Restart the daemon or wait for its next restart, such as an automatic update or a reboot. Then run aicodemetricsd status. Under Session processor, Configured URL shows your processor URL followed by configured but inactive.
Step 5: Turn on processor mode
When laptops report the processor URL, ask DX to turn on processor mode for your organization. Processor mode applies to every laptop in the organization.
Daemons pick up the change when they refresh DX settings, at startup and hourly, without a restart. Configured URL then shows active, and new sessions appear in DX with summaries and evaluations from the processor within about an hour of going idle.
After processor mode is on, each laptop’s sessions follow its daemon version and configuration:
| Daemon | processor_url |
Session uploads |
|---|---|---|
| 0.7.8 or later | Set | Sent to the processor. |
| 0.7.8 or later | Not set | Held in a local queue of up to 256 MiB until processor_url is configured and the daemon restarts. status reports a failure. |
| Older than 0.7.8 | Either | Uploaded to DX, which discards titles and message content. These sessions are not summarized or evaluated. |
Laptops routed to the processor send it scrubbed transcripts and titles regardless of the Transcripts & Agent Experience setting in DX. That setting continues to control transcripts uploaded to DX.
If DX turns processor mode off, laptops return to uploading sessions to DX within an hour. Sessions already queued for the processor are still delivered to it.
Next steps
- Enterprise deployment describes the managed settings channels and installers used to deliver
processor_url. - Security and privacy explains what the daemon collects and how transcripts are scrubbed.
- Troubleshooting covers missing or stale data after rollout.