Pair secret-flag registration with its env fallback · Entire

Pair secret-flag registration with its env fallback

7c04242→main·

Soph·1mo ago·2 files·+19 added/-18 removed

Fold the empty-default StringVar and addSecretEnvFallback into a single addSecretFlag(cmd, dst, name, env, usage) call. Previously each secret flag needed two coordinated statements; a new secret flag could re-introduce the usage leak by registering an envOr default and forgetting the fallback. Pairing them makes the safe handling the only handling.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

Sessions

495d629c11b1View transcript

?\just remove .clawpatch from the commit but then just delete the folder, we don't need to keep itClaude Code·Opus 4.8[1m]·3 steps

Changes

2

73 unmodified lines

74  
75  
76  
77  
78  
77  
78  
79  
81  
82  
83  
84  
80  
81  
82  
83

73 unmodified lines

cmd.Flags().BoolVar(&req.SourceFollowInfoRefsRedirect, "source-follow-info-refs-redirect",
        envBool("GITSYNC_SOURCE_FOLLOW_INFO_REFS_REDIRECT"),
        "send follow-up source RPCs to the final /info/refs redirect host")
    cmd.Flags().StringVar(&req.SourceAuth.Token, "source-token",
        "", "source token/password (env: GITSYNC_SOURCE_TOKEN)")
    addSecretFlag(cmd, &req.SourceAuth.Token, "source-token", "GITSYNC_SOURCE_TOKEN", "source token/password")
    cmd.Flags().StringVar(&req.SourceAuth.Username, "source-username",
        envOr("GITSYNC_SOURCE_USERNAME", "git"), "source basic auth username")
    cmd.Flags().StringVar(&req.SourceAuth.BearerToken, "source-bearer-token",
        "", "source bearer token (env: GITSYNC_SOURCE_BEARER_TOKEN)")
    addSecretEnvFallback(cmd, "source-token", &req.SourceAuth.Token, "GITSYNC_SOURCE_TOKEN")
    addSecretEnvFallback(cmd, "source-bearer-token", &req.SourceAuth.BearerToken, "GITSYNC_SOURCE_BEARER_TOKEN")
    addSecretFlag(cmd, &req.SourceAuth.BearerToken, "source-bearer-token", "GITSYNC_SOURCE_BEARER_TOKEN", "source bearer token")
    cmd.Flags().BoolVar(&req.SourceAuth.SkipTLSVerify, "source-insecure-skip-tls-verify",
        envBool("GITSYNC_SOURCE_INSECURE_SKIP_TLS_VERIFY"),
        "skip TLS certificate verification for the source")

Mcmd/git-sync/convert_sha256.go+2/-6

24 unmodified lines

25  
26  
27  
28  
28  
29  
30  
30  
31  
32  
33  
34  
35  
34  
35  
36  
39  
37  
38  
41  
39  
40  
41  
42  
45  
46  
43  
44  
45  
53 unmodified lines

99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
107  
108  
109  
110  
115  
116  
117  
118

24 unmodified lines

}

func addSourceAuth(cmd *cobra.Command, auth *gitsync.EndpointAuth) {
    cmd.Flags().StringVar(&auth.Token, "source-token", "", "source token/password (env: GITSYNC_SOURCE_TOKEN)")
    addSecretFlag(cmd, &auth.Token, "source-token", "GITSYNC_SOURCE_TOKEN", "source token/password")
    cmd.Flags().StringVar(&auth.Username, "source-username", envOr("GITSYNC_SOURCE_USERNAME", "git"), "source basic auth username")
    cmd.Flags().StringVar(&auth.BearerToken, "source-bearer-token", "", "source bearer token (env: GITSYNC_SOURCE_BEARER_TOKEN)")
    addSecretFlag(cmd, &auth.BearerToken, "source-bearer-token", "GITSYNC_SOURCE_BEARER_TOKEN", "source bearer token")
    cmd.Flags().BoolVar(&auth.SkipTLSVerify, "source-insecure-skip-tls-verify",
        envBool("GITSYNC_SOURCE_INSECURE_SKIP_TLS_VERIFY"),
        "skip TLS certificate verification for the source")
    addSecretEnvFallback(cmd, "source-token", &auth.Token, "GITSYNC_SOURCE_TOKEN")
    addSecretEnvFallback(cmd, "source-bearer-token", &auth.BearerToken, "GITSYNC_SOURCE_BEARER_TOKEN")
}

func addTargetAuth(cmd *cobra.Command, auth *gitsync.EndpointAuth) {
    cmd.Flags().StringVar(&auth.Token, "target-token", "", "target token/password (env: GITSYNC_TARGET_TOKEN)")
    addSecretFlag(cmd, &auth.Token, "target-token", "GITSYNC_TARGET_TOKEN", "target token/password")
    cmd.Flags().StringVar(&auth.Username, "target-username", envOr("GITSYNC_TARGET_USERNAME", "git"), "target basic auth username")
    cmd.Flags().StringVar(&auth.BearerToken, "target-bearer-token", "", "target bearer token (env: GITSYNC_TARGET_BEARER_TOKEN)")
    addSecretFlag(cmd, &auth.BearerToken, "target-bearer-token", "GITSYNC_TARGET_BEARER_TOKEN", "target bearer token")
    cmd.Flags().BoolVar(&auth.SkipTLSVerify, "target-insecure-skip-tls-verify",
        envBool("GITSYNC_TARGET_INSECURE_SKIP_TLS_VERIFY"),
        "skip TLS certificate verification for the target")
    addSecretEnvFallback(cmd, "target-token", &auth.Token, "GITSYNC_TARGET_TOKEN")
    addSecretEnvFallback(cmd, "target-bearer-token", &auth.BearerToken, "GITSYNC_TARGET_BEARER_TOKEN")
}

func addProtocolFlag(cmd *cobra.Command, mode *protocolModeFlag) {
53 unmodified lines

}

// addSecretFlag registers a string flag whose value may also come from an
// environment variable. Unlike non-secret flags, it must NOT register the env
// value as the pflag default: pflag prints non-empty defaults in --help and in
// the usage block dumped on a flag error, which would leak the secret (e.g.
// into CI logs). Registration and the post-parse env fallback are paired in
// one call so a new secret flag cannot accidentally re-introduce the leak by
// reaching for envOr.
func addSecretFlag(cmd *cobra.Command, dst *string, name, env, usage string) {
    cmd.Flags().StringVar(dst, name, "", fmt.Sprintf("%s (env: %s)", usage, env))
    addSecretEnvFallback(cmd, name, dst, env)
}

// addSecretEnvFallback fills *dst from the named environment variable after
// parsing, but only when the flag was not given explicitly. Secret-bearing
// flags must register an empty pflag default rather than the env value:
// pflag prints non-empty defaults in --help and in the usage block dumped on
// a flag error, which would leak the secret (e.g. into CI logs).
// parsing, but only when the flag was not given explicitly.
func addSecretEnvFallback(cmd *cobra.Command, flag string, dst *string, env string) {
    chainPreRunE(cmd, func(cmd *cobra.Command, _ []string) error {
        if cmd.Flags().Changed(flag) {