[Feature] Setting DisplayName and ProfilePicURL for headscale users #812

Open
opened 2025-12-29 02:24:19 +01:00 by adam · 7 comments
Owner

Originally created by @vikanezrimaya on GitHub (Oct 2, 2024).

Use case

Mostly for niceness and completeness. I would like Headscale to know users by name, so that tailscale whois (and related solutions such as tailscale-nginx-auth) can know the user's display name and profile picture.

The OIDC rework document mentioned that CLI-based login should be able to populate these fields, so I hope the maintainers won't mind me filing this as an issue so it could be easily trackable (and to show that this is in fact desirable, and bikeshed over the minute details of the implementation).

Additionally, I may try my hand at implementing this. (I don't really know Go that well, but how hard could it be?)

Description

One or two commands in the Headscale CLI to set the user's display name and the profile picture. Optionally a way to set these fields on user creation.

Contribution

  • I can write the design doc for this feature
  • I can contribute this feature

How can it be implemented?

Exact subcommand/option names subject to bikeshedding.

$ headscale users set -i 1 --display-name "Vika" --profile-pic-url "https://example.com/vika.png"
$ # Additionally, consider the following, to create a user and set their personal data in one step:
$ headscale users create vika --display-name "Vika" --profile-pic-url "https://example.com/vika.png"

Alternatively:

$ headscale users set-display-name -i 1 Vika
$ headscale users set-profile-pic-url -i 1 https://example.com/vika.png
Originally created by @vikanezrimaya on GitHub (Oct 2, 2024). ### Use case Mostly for niceness and completeness. I would like Headscale to know users by name, so that `tailscale whois` (and related solutions such as `tailscale-nginx-auth`) can know the user's display name and profile picture. The [OIDC rework document](https://docs.google.com/document/d/1X85PMxIaVWDF6T_UPji3OeeUqVBcGj_uHRM5CI-AwlY/edit) mentioned that CLI-based login should be able to populate these fields, so I hope the maintainers won't mind me filing this as an issue so it could be easily trackable (and to show that this is in fact desirable, and bikeshed over the minute details of the implementation). Additionally, I may try my hand at implementing this. (I don't really know Go that well, but how hard could it be?) ### Description One or two commands in the Headscale CLI to set the user's display name and the profile picture. Optionally a way to set these fields on user creation. ### Contribution - [ ] I can write the design doc for this feature - [X] I can contribute this feature ### How can it be implemented? Exact subcommand/option names subject to bikeshedding. ```console $ headscale users set -i 1 --display-name "Vika" --profile-pic-url "https://example.com/vika.png" $ # Additionally, consider the following, to create a user and set their personal data in one step: $ headscale users create vika --display-name "Vika" --profile-pic-url "https://example.com/vika.png" ``` Alternatively: ```console $ headscale users set-display-name -i 1 Vika $ headscale users set-profile-pic-url -i 1 https://example.com/vika.png ```
adam added the enhancementhelp wantedgood first issueno-stale-bot labels 2025-12-29 02:24:19 +01:00
Author
Owner

@kradalby commented on GitHub (Oct 4, 2024):

Yes please, I was hoping someone would pick it up so I would appreciate if you want to try to do this :)

You will need to implement the gRPC/API part as part of this, and I think your first example looks nicer for both API and CLI.

--email would also be sensible as I've already thought that it might be nice to do a fallback to services like Gravatar if there is no picture available.

@kradalby commented on GitHub (Oct 4, 2024): Yes please, I was hoping someone would pick it up so I would appreciate if you want to try to do this :) You will need to implement the gRPC/API part as part of this, and I think your first example looks nicer for both API and CLI. `--email` would also be sensible as I've already thought that it might be nice to do a fallback to services like [Gravatar](https://gravatar.com) if there is no picture available.
Author
Owner

@kradalby commented on GitHub (Oct 10, 2024):

@vikanezrimaya As part of a discussion in #2170, a command for setting email would be required, not only sensible.

Let me know if you have started this work so we dont step on each others toes :)

@kradalby commented on GitHub (Oct 10, 2024): @vikanezrimaya As part of a discussion in #2170, a command for setting email would be required, not only sensible. Let me know if you have started this work so we dont step on each others toes :)
Author
Owner

@vikanezrimaya commented on GitHub (Oct 10, 2024):

Kristoffer Dalby @.***> writes:

Let me know if you have started this work so we dont step on each others toes :)

Sorry, haven't had time to get started, so you may proceed with this on
your own if you wish. I bet a regular contributor and a maintainer would
be able to write better code than me anyway due to the familiarity with
the codebase. Making a command to set the profile pic URL would be
trivial copy-pasting in this case.

--
With love,
Vika <3

@vikanezrimaya commented on GitHub (Oct 10, 2024): Kristoffer Dalby ***@***.***> writes: > Let me know if you have started this work so we dont step on each others toes :) Sorry, haven't had time to get started, so you may proceed with this on your own if you wish. I bet a regular contributor and a maintainer would be able to write better code than me anyway due to the familiarity with the codebase. Making a command to set the profile pic URL would be trivial copy-pasting in this case. -- With love, Vika <3
Author
Owner

@kradalby commented on GitHub (Oct 17, 2024):

Please feel free to take a stab at it, I am ran down and wont have time to circle back to it for a while in addition to holidays.

@kradalby commented on GitHub (Oct 17, 2024): Please feel free to take a stab at it, I am ran down and wont have time to circle back to it for a while in addition to holidays.
Author
Owner

@kradalby commented on GitHub (Oct 19, 2024):

I've added the gRPC part and read as I needed it in a test, but the setting of fields is still open.

@kradalby commented on GitHub (Oct 19, 2024): I've added the gRPC part and read as I needed it in a test, but the setting of fields is still open.
Author
Owner

@stalane commented on GitHub (Jun 23, 2025):

guys.. i just want a generic pic for all users

@stalane commented on GitHub (Jun 23, 2025): guys.. i just want a generic pic for all users
Author
Owner

@kanashimia commented on GitHub (Dec 15, 2025):

Just to point out the obvious for completeness:
You can do that very easily using sqlite commandline already, and also it is easier to bulk process users like that.

! cd /var/lib/headscale
! sqlite3 db.sqlite -table
SQLite version 3.51.0 1725-07-30 19:33:53
Enter ".help" for usage hints.
sqlite> .backup db.backup-1.sqlite
sqlite> .tables
api_keys       nodes          pre_auth_keys
migrations     policies       users        
sqlite> select * from users;
+----+------+--------------+-------+---------------------+----------+-----------------+-------------------------------------+-------------------------------------+------------+
| id | name | display_name | email | provider_identifier | provider | profile_pic_url |             created_at              |             updated_at              | deleted_at |
+----+------+--------------+-------+---------------------+----------+-----------------+-------------------------------------+-------------------------------------+------------+
| 1  | john |              |       |                     |          |                 | 1725-12-11 17:35:21.125617165-07:00 | 1725-12-11 17:35:21.125617165-07:00 |            |
+----+------+--------------+-------+---------------------+----------+-----------------+-------------------------------------+-------------------------------------+------------+
sqlite> update users set email = "john.doe@example.com" where id = 1;
sqlite> update users set display_name = "John Doe" where id = 1;
sqlite> select * from users;
+----+------+--------------+----------------------+---------------------+----------+-----------------+-------------------------------------+-------------------------------------+------------+
| id | name | display_name |        email         | provider_identifier | provider | profile_pic_url |             created_at              |             updated_at              | deleted_at |
+----+------+--------------+----------------------+---------------------+----------+-----------------+-------------------------------------+-------------------------------------+------------+
| 1  | john | John Doe     | john.doe@example.com |                     |          |                 | 1725-12-11 17:35:21.125617165-07:00 | 1725-12-11 17:35:21.125617165-07:00 |            |
+----+------+--------------+----------------------+---------------------+----------+-----------------+-------------------------------------+-------------------------------------+------------+
sqlite> 

But having a dedicated flag would be nice ofc, to not live like it is 1725.

@kanashimia commented on GitHub (Dec 15, 2025): Just to point out the obvious for completeness: You can do that very easily using sqlite commandline already, and also it is easier to bulk process users like that. ``` ! cd /var/lib/headscale ! sqlite3 db.sqlite -table SQLite version 3.51.0 1725-07-30 19:33:53 Enter ".help" for usage hints. sqlite> .backup db.backup-1.sqlite sqlite> .tables api_keys nodes pre_auth_keys migrations policies users sqlite> select * from users; +----+------+--------------+-------+---------------------+----------+-----------------+-------------------------------------+-------------------------------------+------------+ | id | name | display_name | email | provider_identifier | provider | profile_pic_url | created_at | updated_at | deleted_at | +----+------+--------------+-------+---------------------+----------+-----------------+-------------------------------------+-------------------------------------+------------+ | 1 | john | | | | | | 1725-12-11 17:35:21.125617165-07:00 | 1725-12-11 17:35:21.125617165-07:00 | | +----+------+--------------+-------+---------------------+----------+-----------------+-------------------------------------+-------------------------------------+------------+ sqlite> update users set email = "john.doe@example.com" where id = 1; sqlite> update users set display_name = "John Doe" where id = 1; sqlite> select * from users; +----+------+--------------+----------------------+---------------------+----------+-----------------+-------------------------------------+-------------------------------------+------------+ | id | name | display_name | email | provider_identifier | provider | profile_pic_url | created_at | updated_at | deleted_at | +----+------+--------------+----------------------+---------------------+----------+-----------------+-------------------------------------+-------------------------------------+------------+ | 1 | john | John Doe | john.doe@example.com | | | | 1725-12-11 17:35:21.125617165-07:00 | 1725-12-11 17:35:21.125617165-07:00 | | +----+------+--------------+----------------------+---------------------+----------+-----------------+-------------------------------------+-------------------------------------+------------+ sqlite> ``` But having a dedicated flag would be nice ofc, to not live like it is 1725.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/headscale#812