Add https://gist.githubusercontent.com/programmerq/6a6c127a94c9018f1a0503fa0140770a/raw/custom-icon.js as a user script using your preferred userscript extension. I used it with TamperMonkey on Chrome with success.
If your Teleport instance is not at teleport.sh, add the Teleport cluster URL as a user match.
To set a custom icon, base64 encode a 72x72 png image, and set it as the value for a label called teleport.dev/icon
.
Resize and/or convert to png if needed. Many logos can also use a reduced color count:
% magick input.png -resize 72x72 -colors 8 output.png
Use a png minifier tool (optional):
% pngcrush output.png output-crush.png
base64 encode:
% cat output-crush.png | base64 -w 0
iVBORw0KGgoAAAANSUhEUgAAAEgAAABIBAMAAACnw650AAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAASUExURQQnSARNcQRwmAWUrw+zyhrK2iUHv+EAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfpAQIRNSYHLo/dAAABhklEQVRIx+2VUZKDIAyGxV5AtAeo2AN0DR6gJVxghftfZROw7u5MKD53mhn1gc8/fyDGpvnE+4Qe64yy2FWhE+K9Cp0R3YFsiJcK1BLj7/VsiI8KdGWoUp9KjP8qrmttDBAS6QIwoyQ3AGSZyFeMwXVC7QCMRQ4MQSxSJcbHLQjCAkRMAFiSmHg8GzSPevJZ6SYaJwipKG2zklDeiaFc0pS2Qdp3NuXxwdCAnE48QQAb8+sKfSj0wvALWYLkrmpheS5dCZL7RcH+/pnKvBXahO2mugeCuhdQEuh9XAu9suyFtxhXWam1DLkNmuWvYYD9xFoMs5GLA+9sztfjakwnbhMs3xrglqCHMRe5fe3T7YCzMdLgmOiAY15QExqKptCZqQmooRxDnWSJTK0spXpM0EWGLLpR696yb8nUkCF080T3ApSVAuaY5XTJOPAHTvdkSdpNmgSGt4EfRs62yfVzXn85e5QpJfobGapMuv6Vm3/5atO3OWAp5av/XNSBbCR14C/1ifeKH4j3bcOdElj9AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDI1LTAxLTAyVDE3OjQ4OjUwKzAwOjAwHMXuNQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyNS0wMS0wMlQxNzo0ODoyNCswMDowMJMSe4MAAAAodEVYdGRhdGU6dGltZXN0YW1wADIwMjUtMDEtMDJUMTc6NTM6MzgrMDA6MDD2YxSBAAAAFXRFWHRleGlmOkNvbG9yU3BhY2UANjU1MzUzewBuAAAAIHRFWHRleGlmOkNvbXBvbmVudHNDb25maWd1cmF0aW9uAC4uLmryoWQAAAAUdEVYdGV4aWY6RXhpZk9mZnNldAAxNjIwuJfX8QAAABV0RVh0ZXhpZjpFeGlmVmVyc2lvbgAwMjEwuHZWeAAAABl0RVh0ZXhpZjpGbGFzaFBpeFZlcnNpb24AMDEwMBLUKKwAAAAOdEVYdGV4aWY6TWFrZQBmbHV4EJmXhAAAABl0RVh0ZXhpZjpQaXhlbFhEaW1lbnNpb24AMTAyNPLFVh8AAAAZdEVYdGV4aWY6UGl4ZWxZRGltZW5zaW9uADEwMjRLPo33AAAAFnRFWHRleGlmOlVzZXJDb21tZW50AEFTQ0lJtONa3gAAABd0RVh0ZXhpZjpZQ2JDclBvc2l0aW9uaW5nADGsD4BjAAAAAElFTkSuQmCC
Add the base64 encoded value to your app definition:
app_service:
apps:
- name: dashboard
uri: http://localhost:9000/
rewrite:
redirect:
- localhost
labels:
teleport.dev/icon: iVBORw0KGgoAAAANSUhEUgAAAEgAAABIBAMAAACnw650AAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAASUExURQQnSARNcQRwmAWUrw+zyhrK2iUHv+EAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfpAQIRNSYHLo/dAAABhklEQVRIx+2VUZKDIAyGxV5AtAeo2AN0DR6gJVxghftfZROw7u5MKD53mhn1gc8/fyDGpvnE+4Qe64yy2FWhE+K9Cp0R3YFsiJcK1BLj7/VsiI8KdGWoUp9KjP8qrmttDBAS6QIwoyQ3AGSZyFeMwXVC7QCMRQ4MQSxSJcbHLQjCAkRMAFiSmHg8GzSPevJZ6SYaJwipKG2zklDeiaFc0pS2Qdp3NuXxwdCAnE48QQAb8+sKfSj0wvALWYLkrmpheS5dCZL7RcH+/pnKvBXahO2mugeCuhdQEuh9XAu9suyFtxhXWam1DLkNmuWvYYD9xFoMs5GLA+9sztfjakwnbhMs3xrglqCHMRe5fe3T7YCzMdLgmOiAY15QExqKptCZqQmooRxDnWSJTK0spXpM0EWGLLpR696yb8nUkCF080T3ApSVAuaY5XTJOPAHTvdkSdpNmgSGt4EfRs62yfVzXn85e5QpJfobGapMuv6Vm3/5atO3OWAp5av/XNSBbCR14C/1ifeKH4j3bcOdElj9AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDI1LTAxLTAyVDE3OjQ4OjUwKzAwOjAwHMXuNQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyNS0wMS0wMlQxNzo0ODoyNCswMDowMJMSe4MAAAAodEVYdGRhdGU6dGltZXN0YW1wADIwMjUtMDEtMDJUMTc6NTM6MzgrMDA6MDD2YxSBAAAAFXRFWHRleGlmOkNvbG9yU3BhY2UANjU1MzUzewBuAAAAIHRFWHRleGlmOkNvbXBvbmVudHNDb25maWd1cmF0aW9uAC4uLmryoWQAAAAUdEVYdGV4aWY6RXhpZk9mZnNldAAxNjIwuJfX8QAAABV0RVh0ZXhpZjpFeGlmVmVyc2lvbgAwMjEwuHZWeAAAABl0RVh0ZXhpZjpGbGFzaFBpeFZlcnNpb24AMDEwMBLUKKwAAAAOdEVYdGV4aWY6TWFrZQBmbHV4EJmXhAAAABl0RVh0ZXhpZjpQaXhlbFhEaW1lbnNpb24AMTAyNPLFVh8AAAAZdEVYdGV4aWY6UGl4ZWxZRGltZW5zaW9uADEwMjRLPo33AAAAFnRFWHRleGlmOlVzZXJDb21tZW50AEFTQ0lJtONa3gAAABd0RVh0ZXhpZjpZQ2JDclBvc2l0aW9uaW5nADGsD4BjAAAAAElFTkSuQmCC
When the Teleport Web UI displays this app, it will show the contents of the custom logo:
The script loops over any img
elements that have src=/web/app/application.svg
. It looks for the div that lists the labels for that resource. Fortunately, the entire label is present in the DOM even if it isn't fully displayed/expanded.
If you create Teleport app definitions via Kubernetes, you'll have a hard time due to Kubernetes' additional restrictions on the label field. They have a maximum of 63 characters, and a fairly strict regex that it must pass. Most URLs and many base64 encoded URLs will be too long to fit into the label on the Kubernetes service object. This means it isn't really practical for use with Kubernetes service -> Teleport app discovery.
This may break in the future if the Teleport Web UI changes. If Teleport has an icon other than applications.svg
(like with grafana), this script will not override it. It works with both Teleport 16.x and 17.x in my quick tests.
It only works when the labels are rendered in the DOM. In list mode, labels are collapsed by default.