From 260e342f2fad09bf66d42687f0b55026b6de286f Mon Sep 17 00:00:00 2001 From: salvacybersec Date: Sun, 5 Apr 2026 15:46:11 +0300 Subject: [PATCH] feat(05-02): add LEGAL.md, embed it, and wire keyhunter legal command - Add LEGAL.md at repo root (109 lines) covering CFAA, Computer Misuse Act, EU Directive 2013/40/EU, responsible use, disclosure, and disclaimer. - Mirror to pkg/legal/LEGAL.md for go:embed (Go cannot traverse parents). - Add pkg/legal package exposing Text() for the embedded markdown. - Add cmd/legal.go registering keyhunter legal subcommand to print it. --- LEGAL.md | 109 ++++++++++++++++++++++++++++++++++++++++ cmd/legal.go | 17 +++++++ cmd/root.go | 1 + pkg/legal/LEGAL.md | 109 ++++++++++++++++++++++++++++++++++++++++ pkg/legal/legal.go | 17 +++++++ pkg/legal/legal_test.go | 22 ++++++++ 6 files changed, 275 insertions(+) create mode 100644 LEGAL.md create mode 100644 cmd/legal.go create mode 100644 pkg/legal/LEGAL.md create mode 100644 pkg/legal/legal.go create mode 100644 pkg/legal/legal_test.go diff --git a/LEGAL.md b/LEGAL.md new file mode 100644 index 0000000..cf83dbd --- /dev/null +++ b/LEGAL.md @@ -0,0 +1,109 @@ +# KeyHunter — Legal Disclaimer for Active Key Verification + +This document describes the legal considerations for using KeyHunter's active +verification feature (`keyhunter scan --verify` and related flags). Read it +carefully before enabling verification. + +## Purpose + +KeyHunter's verification feature makes outbound HTTP calls to third-party +provider APIs (OpenAI, Anthropic, Google, Cohere, and 100+ other LLM/AI +services) in order to determine whether an API key discovered during a scan is +currently live. Verification is **opt-in**: it runs only when you explicitly +pass `--verify`. Passive scanning (the default) never contacts a third party. + +## What --verify Does + +- Sends a single lightweight HTTP request per discovered key to that provider's + documented verify endpoint (for example, `GET /v1/models` for OpenAI-style + APIs). +- Uses only the HTTP methods and bodies documented in the provider's public + API reference. +- Does **not** modify, create, delete, or otherwise mutate any account or data + on the provider's side. +- Reads only the metadata the provider voluntarily returns in the response + (organization name, rate limit tier, available models). +- Masks keys in all logs and output by default; the raw key is never written + to disk unless you explicitly pass `--unmask`. + +## Legal Considerations + +Verifying an API key that you do not own or do not have explicit permission to +test may constitute unauthorized access under computer-crime statutes in many +jurisdictions, including but not limited to: + +- **United States** — Computer Fraud and Abuse Act, 18 U.S.C. § 1030 (CFAA). + Unauthorized access to a "protected computer" (broadly interpreted to + include any internet-connected server) can result in civil and criminal + liability. +- **United Kingdom** — Computer Misuse Act 1990, sections 1–3. Unauthorized + access, unauthorized access with intent, and unauthorized acts with intent + to impair are all criminal offences. +- **European Union** — Directive 2013/40/EU on attacks against information + systems, transposed into national law by each member state. +- **Provider Terms of Service** — In addition to statutory law, every provider + imposes contractual terms that typically forbid using credentials you are + not authorized to use. Violations can result in account termination and + civil claims for damages. + +Making an API call with a stolen or leaked key, **even a single request that +does nothing**, may legally qualify as "access without authorization" in these +frameworks. + +## Responsible Use + +You should only use `--verify` in the following scenarios: + +- **Your own keys** — keys that belong to accounts you personally own and + operate. +- **Authorized engagements** — penetration tests, red-team exercises, or bug + bounty programs where the scope document **explicitly authorizes** active + verification of credentials belonging to the target. +- **Your own CI/CD pipelines** — scanning your own source code, your + organization's source code (with employer authorization), or container + images you are responsible for. + +Do **not** run `--verify` against keys you found in random public +repositories, pastes, or leak dumps belonging to third parties without first +obtaining the owner's consent. + +## Responsible Disclosure + +If you discover a leaked API key that belongs to someone else: + +1. Do **not** verify it, use it, or publish it. +2. Contact the key owner directly. Look for a `security.txt` file at + `https:///.well-known/security.txt`, a security contact on their + website, or an entry in a vulnerability disclosure platform. +3. Provide enough detail for them to rotate the key (where you found it, what + provider it targets, the masked prefix) without exposing the raw secret in + your disclosure channel. +4. Give the owner reasonable time to respond and rotate before any public + disclosure. + +## Disclaimer + +KeyHunter is provided "as is", without warranty of any kind, express or +implied, including but not limited to the warranties of merchantability, +fitness for a particular purpose, and non-infringement. The authors and +contributors of KeyHunter disclaim all liability for any damages, direct or +indirect, arising from the use or misuse of this tool. **You, the user, are +solely responsible** for ensuring that your use of KeyHunter complies with all +applicable laws, regulations, contracts, and terms of service in your +jurisdiction and the jurisdiction of any service you interact with. + +## Consent Record + +The first time you run `keyhunter scan --verify`, KeyHunter displays an +interactive consent prompt summarizing this disclaimer. You must type `yes` +(case-insensitive) to proceed. Your decision is persisted in the local SQLite +settings table under the key `verify.consent`. Granted consent is sticky +across runs; declined consent is not, so you will be re-prompted next time +(in case you change your mind or run in a different environment). + +To review this document at any time, run: + + keyhunter legal + +To reset consent and force a re-prompt, clear the `verify.consent` setting +from your KeyHunter database. diff --git a/cmd/legal.go b/cmd/legal.go new file mode 100644 index 0000000..81ed14a --- /dev/null +++ b/cmd/legal.go @@ -0,0 +1,17 @@ +package cmd + +import ( + "fmt" + + "github.com/salvacybersec/keyhunter/pkg/legal" + "github.com/spf13/cobra" +) + +var legalCmd = &cobra.Command{ + Use: "legal", + Short: "Print the legal disclaimer for the --verify feature", + RunE: func(cmd *cobra.Command, args []string) error { + fmt.Println(legal.Text()) + return nil + }, +} diff --git a/cmd/root.go b/cmd/root.go index 81d62ad..62f0350 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -33,6 +33,7 @@ func init() { rootCmd.AddCommand(scanCmd) rootCmd.AddCommand(providersCmd) rootCmd.AddCommand(configCmd) + rootCmd.AddCommand(legalCmd) // Stub commands for future phases (per CLI-01 requirement of 11 commands) rootCmd.AddCommand(verifyCmd) rootCmd.AddCommand(importCmd) diff --git a/pkg/legal/LEGAL.md b/pkg/legal/LEGAL.md new file mode 100644 index 0000000..cf83dbd --- /dev/null +++ b/pkg/legal/LEGAL.md @@ -0,0 +1,109 @@ +# KeyHunter — Legal Disclaimer for Active Key Verification + +This document describes the legal considerations for using KeyHunter's active +verification feature (`keyhunter scan --verify` and related flags). Read it +carefully before enabling verification. + +## Purpose + +KeyHunter's verification feature makes outbound HTTP calls to third-party +provider APIs (OpenAI, Anthropic, Google, Cohere, and 100+ other LLM/AI +services) in order to determine whether an API key discovered during a scan is +currently live. Verification is **opt-in**: it runs only when you explicitly +pass `--verify`. Passive scanning (the default) never contacts a third party. + +## What --verify Does + +- Sends a single lightweight HTTP request per discovered key to that provider's + documented verify endpoint (for example, `GET /v1/models` for OpenAI-style + APIs). +- Uses only the HTTP methods and bodies documented in the provider's public + API reference. +- Does **not** modify, create, delete, or otherwise mutate any account or data + on the provider's side. +- Reads only the metadata the provider voluntarily returns in the response + (organization name, rate limit tier, available models). +- Masks keys in all logs and output by default; the raw key is never written + to disk unless you explicitly pass `--unmask`. + +## Legal Considerations + +Verifying an API key that you do not own or do not have explicit permission to +test may constitute unauthorized access under computer-crime statutes in many +jurisdictions, including but not limited to: + +- **United States** — Computer Fraud and Abuse Act, 18 U.S.C. § 1030 (CFAA). + Unauthorized access to a "protected computer" (broadly interpreted to + include any internet-connected server) can result in civil and criminal + liability. +- **United Kingdom** — Computer Misuse Act 1990, sections 1–3. Unauthorized + access, unauthorized access with intent, and unauthorized acts with intent + to impair are all criminal offences. +- **European Union** — Directive 2013/40/EU on attacks against information + systems, transposed into national law by each member state. +- **Provider Terms of Service** — In addition to statutory law, every provider + imposes contractual terms that typically forbid using credentials you are + not authorized to use. Violations can result in account termination and + civil claims for damages. + +Making an API call with a stolen or leaked key, **even a single request that +does nothing**, may legally qualify as "access without authorization" in these +frameworks. + +## Responsible Use + +You should only use `--verify` in the following scenarios: + +- **Your own keys** — keys that belong to accounts you personally own and + operate. +- **Authorized engagements** — penetration tests, red-team exercises, or bug + bounty programs where the scope document **explicitly authorizes** active + verification of credentials belonging to the target. +- **Your own CI/CD pipelines** — scanning your own source code, your + organization's source code (with employer authorization), or container + images you are responsible for. + +Do **not** run `--verify` against keys you found in random public +repositories, pastes, or leak dumps belonging to third parties without first +obtaining the owner's consent. + +## Responsible Disclosure + +If you discover a leaked API key that belongs to someone else: + +1. Do **not** verify it, use it, or publish it. +2. Contact the key owner directly. Look for a `security.txt` file at + `https:///.well-known/security.txt`, a security contact on their + website, or an entry in a vulnerability disclosure platform. +3. Provide enough detail for them to rotate the key (where you found it, what + provider it targets, the masked prefix) without exposing the raw secret in + your disclosure channel. +4. Give the owner reasonable time to respond and rotate before any public + disclosure. + +## Disclaimer + +KeyHunter is provided "as is", without warranty of any kind, express or +implied, including but not limited to the warranties of merchantability, +fitness for a particular purpose, and non-infringement. The authors and +contributors of KeyHunter disclaim all liability for any damages, direct or +indirect, arising from the use or misuse of this tool. **You, the user, are +solely responsible** for ensuring that your use of KeyHunter complies with all +applicable laws, regulations, contracts, and terms of service in your +jurisdiction and the jurisdiction of any service you interact with. + +## Consent Record + +The first time you run `keyhunter scan --verify`, KeyHunter displays an +interactive consent prompt summarizing this disclaimer. You must type `yes` +(case-insensitive) to proceed. Your decision is persisted in the local SQLite +settings table under the key `verify.consent`. Granted consent is sticky +across runs; declined consent is not, so you will be re-prompted next time +(in case you change your mind or run in a different environment). + +To review this document at any time, run: + + keyhunter legal + +To reset consent and force a re-prompt, clear the `verify.consent` setting +from your KeyHunter database. diff --git a/pkg/legal/legal.go b/pkg/legal/legal.go new file mode 100644 index 0000000..630d3b4 --- /dev/null +++ b/pkg/legal/legal.go @@ -0,0 +1,17 @@ +// Package legal exposes the KeyHunter legal disclaimer as a compile-time +// embedded string. +// +// Note: Go's //go:embed directive cannot traverse parent directories, so the +// canonical LEGAL.md lives at the repo root (for user visibility) AND a +// byte-identical copy lives at pkg/legal/LEGAL.md (for embedding). This +// mirrors the dual-location pattern used in Phase 1 for provider YAML files +// (providers/*.yaml vs pkg/providers/definitions/*.yaml). +package legal + +import _ "embed" + +//go:embed LEGAL.md +var legalMarkdown string + +// Text returns the embedded LEGAL.md contents. +func Text() string { return legalMarkdown } diff --git a/pkg/legal/legal_test.go b/pkg/legal/legal_test.go new file mode 100644 index 0000000..3ceed32 --- /dev/null +++ b/pkg/legal/legal_test.go @@ -0,0 +1,22 @@ +package legal + +import ( + "strings" + "testing" +) + +func TestText_NonEmpty(t *testing.T) { + got := Text() + if len(got) < 500 { + t.Fatalf("Text() too short: got %d bytes, want > 500", len(got)) + } +} + +func TestText_ContainsKeyPhrases(t *testing.T) { + got := Text() + for _, phrase := range []string{"CFAA", "Responsible Use", "Disclaimer"} { + if !strings.Contains(got, phrase) { + t.Errorf("Text() missing required phrase %q", phrase) + } + } +}