ghmk commited on
Commit
c078ea1
Β·
1 Parent(s): e494e0c

Add security improvements for public deployment

Browse files

- Add warning banner when API key not set
- Add helpful link to get free API key
- Clarify that API keys are per-session only
- Create comprehensive SECURITY.md documentation
- Update license info in sidebar (Apache -> AGPL)

Files changed (2) hide show
  1. SECURITY.md +261 -0
  2. character_forge_image/app.py +21 -5
SECURITY.md ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Security & Privacy - Character Forge
2
+
3
+ ## πŸ”’ API Key Security
4
+
5
+ ### How API Keys Work
6
+
7
+ Character Forge is designed to be deployed as a **public HuggingFace Space** where each user provides their own Gemini API key.
8
+
9
+ **βœ… SECURE: Each user's API key stays in THEIR session only**
10
+
11
+ - API keys are stored in Streamlit's `session_state`
12
+ - Session state is **isolated per browser session**
13
+ - Your API key is **NEVER shared** with other users
14
+ - Your API key is **NEVER stored** on the server
15
+ - Your API key is **NEVER logged** or saved to disk
16
+
17
+ ### Deployment Configuration
18
+
19
+ **For Public Spaces (Recommended):**
20
+
21
+ ❌ **DO NOT** add `GEMINI_API_KEY` to HuggingFace Repository Secrets
22
+
23
+ If you add your API key as a secret, ALL users will use YOUR key and you'll pay for their usage!
24
+
25
+ Instead:
26
+ - Leave Repository Secrets empty
27
+ - Each user enters their own API key in the sidebar
28
+ - Users get their own free API key from [Google AI Studio](https://aistudio.google.com/app/apikey)
29
+
30
+ **For Private Spaces (Your Personal Use):**
31
+
32
+ βœ… **DO** add `GEMINI_API_KEY` to Repository Secrets
33
+
34
+ If your Space is set to Private:
35
+ - Only you (and people you invite) can access it
36
+ - Safe to add your API key as a secret
37
+ - Convenient - no need to enter it each time
38
+
39
+ ---
40
+
41
+ ## πŸ” Privacy & Data Handling
42
+
43
+ ### What Data is Processed?
44
+
45
+ When you generate images:
46
+ 1. **Your input images** are sent to Google's Gemini API
47
+ 2. **Your text prompts** are sent to Google's Gemini API
48
+ 3. **Generated images** are returned to your browser
49
+ 4. **Nothing is stored** on HuggingFace servers (files are temporary)
50
+
51
+ ### Where Does Data Go?
52
+
53
+ ```
54
+ Your Browser
55
+ ↓ (upload image + prompt)
56
+ HuggingFace Space (temporary processing)
57
+ ↓ (forward to API)
58
+ Google Gemini API (image generation)
59
+ ↓ (return generated image)
60
+ HuggingFace Space (temporary)
61
+ ↓ (download image)
62
+ Your Browser (you save it)
63
+ ```
64
+
65
+ ### Data Retention
66
+
67
+ **On HuggingFace:**
68
+ - Generated images are stored in `/tmp/` (deleted after session ends)
69
+ - No permanent storage
70
+ - No logs of your generations
71
+
72
+ **On Google Gemini API:**
73
+ - Review [Google's Privacy Policy](https://policies.google.com/privacy)
74
+ - Gemini API processes your data per their terms
75
+ - Check [Gemini API Terms](https://ai.google.dev/terms)
76
+
77
+ ---
78
+
79
+ ## πŸ›‘οΈ Best Practices
80
+
81
+ ### For Users:
82
+
83
+ 1. **Get Your Own API Key**
84
+ - Visit [Google AI Studio](https://aistudio.google.com/app/apikey)
85
+ - Create a free API key
86
+ - Enter it in the Character Forge sidebar
87
+ - Keep it private (don't share screenshots with your key visible)
88
+
89
+ 2. **Monitor Your Usage**
90
+ - Check your usage at [Google AI Studio](https://aistudio.google.com/)
91
+ - Free tier: 15 requests/minute, 1500/day
92
+ - Paid tier: ~$0.03 per image
93
+
94
+ 3. **Protect Your Key**
95
+ - Never share your API key publicly
96
+ - Don't commit it to git repositories
97
+ - Use environment variables for local development
98
+
99
+ ### For Space Owners:
100
+
101
+ 1. **Public Space = No Secrets**
102
+ - Don't add `GEMINI_API_KEY` to Repository Secrets
103
+ - Let users provide their own keys
104
+ - Zero cost to you!
105
+
106
+ 2. **Private Space = Secrets OK**
107
+ - Add your key as a secret if Space is private
108
+ - Only you and invited users can access
109
+ - You control who uses your key
110
+
111
+ 3. **Monitor Your Space**
112
+ - Check HuggingFace Space logs for errors
113
+ - Monitor unusual activity
114
+ - Consider adding rate limiting if needed
115
+
116
+ ---
117
+
118
+ ## πŸ” Code Audit
119
+
120
+ The security model is implemented in these files:
121
+
122
+ ### Session State Isolation
123
+ - **File**: `character_forge_image/app.py`
124
+ - **Lines**: 40-41, 118-119
125
+ - **Behavior**: API key stored in `st.session_state.gemini_api_key`
126
+ - **Isolation**: Streamlit guarantees session state is per-user
127
+
128
+ ### API Key Retrieval
129
+ - **File**: `character_forge_image/config/settings.py`
130
+ - **Lines**: 54-61
131
+ - **Behavior**: Checks environment variable, falls back to None
132
+ - **Safe**: If no env var, users must provide their own
133
+
134
+ ### API Key Usage
135
+ - **File**: `character_forge_image/core/gemini_client.py`
136
+ - **Lines**: 35-46
137
+ - **Behavior**: API key passed to Google's SDK
138
+ - **Safe**: Never logged, never stored
139
+
140
+ ---
141
+
142
+ ## ⚠️ Common Mistakes to Avoid
143
+
144
+ ### ❌ DON'T: Share Your API Key
145
+ ```python
146
+ # NEVER do this in public code
147
+ GEMINI_API_KEY = "AIzaSy..." # ❌ Hard-coded key
148
+ ```
149
+
150
+ ### ❌ DON'T: Add Secret to Public Space
151
+ ```yaml
152
+ # In HuggingFace Settings β†’ Repository Secrets
153
+ # If Space is PUBLIC:
154
+ GEMINI_API_KEY: AIzaSy... # ❌ Everyone uses your key!
155
+ ```
156
+
157
+ ### βœ… DO: Let Users Provide Keys
158
+ ```python
159
+ # This is what Character Forge does:
160
+ st.session_state.gemini_api_key = user_input # βœ… Per-user key
161
+ ```
162
+
163
+ ### βœ… DO: Use Environment Variables Locally
164
+ ```bash
165
+ # For local development:
166
+ export GEMINI_API_KEY="your-key-here"
167
+ streamlit run app.py
168
+ ```
169
+
170
+ ---
171
+
172
+ ## πŸ“Š Cost Implications
173
+
174
+ ### Public Space (Users Provide Keys)
175
+ - **Your Cost**: $0
176
+ - **User Cost**: Their own API usage
177
+ - **Benefit**: Scalable, no abuse risk
178
+
179
+ ### Public Space (You Provide Key) ❌ NOT RECOMMENDED
180
+ - **Your Cost**: Unlimited! Users can drain your account
181
+ - **Risk**: High abuse potential
182
+ - **Benefit**: None
183
+
184
+ ### Private Space (You Provide Key)
185
+ - **Your Cost**: Only your usage
186
+ - **Risk**: Low (only you and invited users)
187
+ - **Benefit**: Convenient
188
+
189
+ ---
190
+
191
+ ## 🚨 Security Incident Response
192
+
193
+ If you suspect your API key has been compromised:
194
+
195
+ 1. **Revoke the key immediately**
196
+ - Go to [Google AI Studio](https://aistudio.google.com/)
197
+ - Delete the compromised key
198
+
199
+ 2. **Create a new key**
200
+ - Generate a fresh API key
201
+ - Update your local environment
202
+
203
+ 3. **Review usage**
204
+ - Check your API usage logs
205
+ - Look for unusual activity
206
+
207
+ 4. **Update security**
208
+ - Ensure key isn't in git history
209
+ - Update `.gitignore` if needed
210
+ - Rotate keys regularly
211
+
212
+ ---
213
+
214
+ ## βœ… Verification
215
+
216
+ To verify the security model is working:
217
+
218
+ 1. **Open two different browsers** (e.g., Chrome and Firefox)
219
+ 2. **Visit your Space** in both browsers
220
+ 3. **Enter different API keys** in each browser
221
+ 4. **Generate images** in both
222
+ 5. **Verify**: Each browser uses its own key (check Google API usage)
223
+
224
+ If both browsers share the same key β†’ **SECURITY ISSUE**
225
+ If each browser has its own key β†’ **WORKING CORRECTLY βœ…**
226
+
227
+ ---
228
+
229
+ ## πŸ“ž Reporting Security Issues
230
+
231
+ If you find a security vulnerability:
232
+
233
+ 1. **DO NOT** create a public GitHub issue
234
+ 2. **Email**: gk@ghmk.de
235
+ 3. **Subject**: "Character Forge Security Issue"
236
+ 4. **Include**:
237
+ - Description of the vulnerability
238
+ - Steps to reproduce
239
+ - Potential impact
240
+
241
+ We'll respond within 48 hours.
242
+
243
+ ---
244
+
245
+ ## πŸ“œ License & Compliance
246
+
247
+ Character Forge is licensed under **GNU AGPL v3.0**
248
+
249
+ This means:
250
+ - βœ… Free to use
251
+ - βœ… Open source
252
+ - βœ… Modifications must be shared
253
+ - ❌ Cannot be integrated into proprietary software
254
+
255
+ For security audits, the full source code is available at:
256
+ https://huggingface.co/spaces/ghmk/character_forge
257
+
258
+ ---
259
+
260
+ **Last Updated**: 2025-01-12
261
+ **Version**: 1.0.0
character_forge_image/app.py CHANGED
@@ -67,6 +67,14 @@ def render_header():
67
  """
68
  )
69
 
 
 
 
 
 
 
 
 
70
  st.divider()
71
 
72
 
@@ -109,11 +117,15 @@ def render_sidebar():
109
  st.markdown("## Settings")
110
 
111
  # API Key input (for Gemini)
 
 
 
112
  api_key = st.text_input(
113
  "Gemini API Key",
114
- value=st.session_state.gemini_api_key,
115
  type="password",
116
- help="Enter your Google Gemini API key. Required for Gemini backend."
 
117
  )
118
  if api_key != st.session_state.gemini_api_key:
119
  st.session_state.gemini_api_key = api_key
@@ -140,11 +152,15 @@ def render_sidebar():
140
 
141
  ---
142
  **License:**
143
- Apache 2.0
 
 
 
 
144
 
145
  **Get Started:**
146
- - [Quick Start Guide](https://github.com/yourusername/character-forge)
147
- - [Documentation](https://github.com/yourusername/character-forge/tree/main/docs)
148
  """
149
  )
150
 
 
67
  """
68
  )
69
 
70
+ # Show API key warning if not configured
71
+ if not st.session_state.get('gemini_api_key'):
72
+ st.warning(
73
+ "⚠️ **API Key Required**: Please enter your Gemini API key in the sidebar to start generating. "
74
+ "Get a free API key at [Google AI Studio](https://aistudio.google.com/app/apikey).",
75
+ icon="πŸ”‘"
76
+ )
77
+
78
  st.divider()
79
 
80
 
 
117
  st.markdown("## Settings")
118
 
119
  # API Key input (for Gemini)
120
+ st.markdown("### πŸ”‘ API Key")
121
+ st.info("Get your FREE API key at [Google AI Studio](https://aistudio.google.com/app/apikey)")
122
+
123
  api_key = st.text_input(
124
  "Gemini API Key",
125
+ value=st.session_state.gemini_api_key or "",
126
  type="password",
127
+ help="Enter your Google Gemini API key. Required for Gemini backend. Your key stays in YOUR session only.",
128
+ placeholder="Enter your API key here..."
129
  )
130
  if api_key != st.session_state.gemini_api_key:
131
  st.session_state.gemini_api_key = api_key
 
152
 
153
  ---
154
  **License:**
155
+ GNU AGPL v3.0
156
+
157
+ **Privacy:**
158
+ Your API key is stored only in YOUR session.
159
+ It is never shared with other users.
160
 
161
  **Get Started:**
162
+ - [Get API Key](https://aistudio.google.com/app/apikey)
163
+ - [HuggingFace Space](https://huggingface.co/spaces/ghmk/character_forge)
164
  """
165
  )
166