| 1 | # IBKR Connector Runtime |
| 2 | |
| 3 | `ibkr-connector` manages one user-specific Interactive Brokers Client Portal Gateway runtime session. It contains process management and read-only Gateway proxy operations only. Portfolio synchronization and broker business logic remain in `broker-service`. |
| 4 | |
| 5 | ## Artifact policy |
| 6 | |
| 7 | Do not commit the IBKR Client Portal Gateway ZIP, extracted binaries, certificates, or bundled proprietary files to this repository. The runtime expects an official package supplied outside the repository: |
| 8 | |
| 9 | - DEV: mount or provide the locally downloaded and extracted official package. |
| 10 | - PRD: keep the artifact source configuration-driven and disabled until legal and deployment approval exists. |
| 11 | |
| 12 | Required configuration: |
| 13 | |
| 14 | - `AIP_IBKR_GATEWAY_PACKAGE_PATH`: path to the extracted official package containing `bin/run.sh` and `root/conf.yaml`. |
| 15 | - `AIP_IBKR_GATEWAY_BASE_URL`: Gateway API base URL reachable from the connector process, for example the Gateway's `/v1/api` endpoint. |
| 16 | - `AIP_INTERNAL_TOKEN`: shared internal token used by broker-service. |
| 17 | - `AIP_IBKR_LOGIN_PUBLIC_BASE_URL`: external base route that fronts this connector, if the returned login URL must be absolute. |
| 18 | |
| 19 | DEV-only TLS: |
| 20 | |
| 21 | - `AIP_IBKR_GATEWAY_TLS_VERIFY=false` may be used only for the connector's local Gateway client when the official Gateway uses a self-signed certificate. |
| 22 | - PRD must keep TLS verification enabled unless a deployment-approved certificate trust chain is configured. |
| 23 | |
| 24 | ## DEV image build |
| 25 | |
| 26 | From the repository root: |
| 27 | |
| 28 | ```powershell |
| 29 | docker build -f services/ibkr-connector/Dockerfile -t ai-investment/ibkr-connector:dev . |
| 30 | ``` |
| 31 | |
| 32 | ## DEV container run |
| 33 | |
| 34 | Replace the package path with the local extracted official IBKR Gateway package. This command mounts it read-only and does not bake IBKR binaries into the image: |
| 35 | |
| 36 | ```powershell |
| 37 | docker run --rm -p 18080:8080 ` |
| 38 | -e AIP_IBKR_GATEWAY_PACKAGE_PATH=/opt/ibkr/clientportal.gw ` |
| 39 | -e AIP_IBKR_GATEWAY_BASE_URL=<GATEWAY_API_BASE_URL> ` |
| 40 | -e AIP_IBKR_GATEWAY_TLS_VERIFY=false ` |
| 41 | -e AIP_INTERNAL_TOKEN=dev-internal-connector-token-change-me ` |
| 42 | -e AIP_IBKR_LOGIN_PUBLIC_BASE_URL=http://127.0.0.1:18080 ` |
| 43 | -v "<OFFICIAL_IBKR_GATEWAY_PACKAGE_PATH>:/opt/ibkr/clientportal.gw:ro" ` |
| 44 | ai-investment/ibkr-connector:dev |
| 45 | ``` |
| 46 | |
| 47 | The runtime launches only: |
| 48 | |
| 49 | ```text |
| 50 | bin/run.sh root/conf.yaml |
| 51 | ``` |
| 52 | |
| 53 | It does not shell-execute arbitrary commands. |
| 54 | |
| 55 | ## Internal API |
| 56 | |
| 57 | All `/internal/**` routes require `X-Internal-Token` and user ownership via `X-AIP-User-Id` after creation. |
| 58 | |
| 59 | - `POST /internal/connectors` |
| 60 | - `GET /internal/connectors/{id}/status` |
| 61 | - `GET /internal/connectors/{id}/login` |
| 62 | - `POST /internal/connectors/{id}/stop` |
| 63 | - `POST /internal/connectors/{id}/restart` |
| 64 | - `GET /internal/connectors/{id}/accounts` |
| 65 | - `GET /internal/connectors/{id}/positions?account_id={accountId}&page=0` |
| 66 | - `GET /internal/connectors/{id}/ledger?account_id={accountId}` |
| 67 | |
| 68 | Trading routes are intentionally absent. Order submission, modification, cancellation, and reply endpoints are not proxied. |
| 69 | |
| 70 | ## Isolation model |
| 71 | |
| 72 | The service contract is per-user and per-connector. This DEV runtime enforces one active connector per process so a deployed pod/container owns exactly one IBKR Gateway session: |
| 73 | |
| 74 | ```text |
| 75 | User A -> Connector A runtime -> Gateway A |
| 76 | User B -> Connector B runtime -> Gateway B |
| 77 | ``` |
| 78 | |
| 79 | Kubernetes production orchestration should create one runtime pod per connector session. The current Helm chart deploys a single disabled-by-default runtime suitable for DEV validation and is not a claim of dynamic multi-user pod orchestration. |