@@ -1186,9 +1186,9 @@ func (a *agent) createOrUpdateNetwork(manifestOK, networkOK *checkpoint) func(co
1186
1186
network := a .network
1187
1187
a .closeMutex .Unlock ()
1188
1188
if network == nil {
1189
- keySeed , err := WorkspaceKeySeed (manifest .WorkspaceID , manifest .AgentName )
1189
+ keySeed , err := SSHKeySeed (manifest .OwnerName , manifest . WorkspaceName , manifest .AgentName )
1190
1190
if err != nil {
1191
- return xerrors .Errorf ("generate seed from workspace id : %w" , err )
1191
+ return xerrors .Errorf ("generate SSH key seed : %w" , err )
1192
1192
}
1193
1193
// use the graceful context here, because creating the tailnet is not itself tied to the
1194
1194
// agent API.
@@ -2068,12 +2068,31 @@ func PrometheusMetricsHandler(prometheusRegistry *prometheus.Registry, logger sl
2068
2068
})
2069
2069
}
2070
2070
2071
- // WorkspaceKeySeed converts a WorkspaceID UUID and agent name to an int64 hash.
2071
+ // SSHKeySeed converts an owner userName, workspaceName and agentName to an int64 hash.
2072
2072
// This uses the FNV-1a hash algorithm which provides decent distribution and collision
2073
2073
// resistance for string inputs.
2074
- func WorkspaceKeySeed (workspaceID uuid.UUID , agentName string ) (int64 , error ) {
2074
+ //
2075
+ // Why owner username, workspace name, and agent name? These are the components that are used in hostnames for the
2076
+ // workspace over SSH, and so we want the workspace to have a stable key with respect to these. We don't use the
2077
+ // respective UUIDs. The workspace UUID would be different if you delete and recreate a workspace with the same name.
2078
+ // The agent UUID is regenerated on each build. Since Coder's Tailnet networking is handling the authentication, we
2079
+ // should not be showing users warnings about host SSH keys.
2080
+ func SSHKeySeed (userName , workspaceName , agentName string ) (int64 , error ) {
2075
2081
h := fnv .New64a ()
2076
- _ , err := h .Write (workspaceID [:])
2082
+ _ , err := h .Write ([]byte (userName ))
2083
+ if err != nil {
2084
+ return 42 , err
2085
+ }
2086
+ // null separators between strings so that (dog, foodstuff) is distinct from (dogfood, stuff)
2087
+ _ , err = h .Write ([]byte {0 })
2088
+ if err != nil {
2089
+ return 42 , err
2090
+ }
2091
+ _ , err = h .Write ([]byte (workspaceName ))
2092
+ if err != nil {
2093
+ return 42 , err
2094
+ }
2095
+ _ , err = h .Write ([]byte {0 })
2077
2096
if err != nil {
2078
2097
return 42 , err
2079
2098
}
0 commit comments