Development Security
Security has always mattered. In the AI era, it matters even more.
AI can generate code faster than a person can review it. A change may look complete and ready to merge, even when it introduces a security problem. Faster development does not mean a change is safer, and it does not reduce the need for careful review.
Before changing code, understand which parts of the system the change can affect. Then check those same areas before committing and deploying it.
For example, changing a button's color is very different from changing who can read an order or how a payment is marked as complete. Both may involve only a few lines of code, but their security risks are not the same.
The Development path explains how changes move through the development process and how much of the system they can affect. This page focuses on the security boundaries those changes must respect.
1. Understand the Security Boundaries
Fatleon relies on several services, each responsible for a different part of the system. Some security responsibilities belong to those services; others remain part of the application.
The architecture is documented in Architecture. The table below focuses on what each system protects and what Fatleon must handle correctly.
| System | What it handles | What Fatleon must protect |
|---|---|---|
| Amazon Cognito | Customer, admin, and affiliate accounts | Who is placed in Admins or Affiliates. Admins open the admin. Admins and Affiliates open the referral program. There is no finer role matrix. |
| Stripe or PayPal | Payment details and payment confirmation | Payment configuration, webhook verification, and the rules for marking orders as paid |
| AWS AppSync, Lambda, and DynamoDB | Store data and application logic | Authorization, data access, order processing, and sensitive operations |
| Your email provider | Sign-up codes, password resets, and order emails | SMTP credentials, email configuration, and the information included in messages |
| Amazon S3 and CloudFront | Product images, banners, and other files | Which files are uploaded and which files are publicly accessible |
Accounts and permissions
Cognito manages authentication, including customer sign-in and passwords. Fatleon should not store customer passwords itself.
The application still controls who receives admin or affiliate privileges. The /setup flow is available only while the Cognito user pool is empty, so it cannot be used to create additional initial users after accounts already exist.
A change to authentication or role assignment can affect the entire store, even if the change looks small.
Payments and checkout
Stripe and PayPal handle payment details and provide payment confirmation through their respective payment flows.
Fatleon is responsible for configuring the integrations correctly and ensuring that an order is marked as paid only through the intended payment-processing path.
Payment API keys, webhook signing secrets, and the PayPal Webhook ID belong in System → Payment Settings. The configured webhook endpoint must match the shop's domain.
When a webhook reaches the application, the original request and its signature headers must be forwarded to Lambda so the webhook can be verified correctly. Do not remove or alter information needed for verification.
Mock payments must remain disabled on the customer-facing store. Test keys and mock payments belong in development or sandbox environments.
Store data and authorization
AppSync and DynamoDB handle application data, including products, carts, orders, and content. Lambda handles sensitive operations such as checkout, payment processing, returns, admin mutations, and email delivery.
The application must enforce authorization at the appropriate layer. A shopper must not be able to read another shopper's orders or perform operations reserved for admins or backend functions.
For guest checkout, a customer can reopen an order using the token included in the order confirmation email. The application must validate that token whenever it is used to access the order.
Do not rely on hiding a button or page in the frontend to protect sensitive data. The backend must enforce the relevant permissions.
Email and file storage
Fatleon sends sign-up codes, password-reset messages, and order emails through the email provider you configure.
Store the SMTP host, sender details, and mailbox password in System → Email Settings. These settings must not be committed to the repository or exposed in browser code.
Product images and banners are stored in S3 and delivered through CloudFront. The configured public distribution exposes the admin-pictures/ prefix. Changes to file uploads or public access rules must preserve the intended access boundaries.
Keep secrets out of the codebase
Payment keys, webhook secrets, SMTP passwords, and the Blog Content API token are configured in the admin interface after the store has been set up.
The application build does not need these production secrets. Keep them out of source files, Git commits, browser bundles, logs, and other places where unauthorized people could access them.
The rule is simple: configuration belongs in the appropriate settings or secret-management mechanism, not in the source code.
2. Identify the Risk Before You Edit
Before starting a change, identify which parts of the system it could affect. Use the categories below to decide what needs to be reviewed and tested.
| Change type | Questions to ask |
|---|---|
| Admin and configuration | Are production keys used only on the customer store, with test keys reserved for the sandbox? Is Mock disabled on the customer-facing store? Does the webhook URL match the shop's domain? |
| Frontend | Is this only a visual change, a label, or a navigation link? Could the change expose a token, a secret, or another shopper's data? |
| Page or route | Does the page access orders, carts, or admin-only data? Does a shopper see only records they are authorized to access? |
| Backend and authorization | Does a schema or resolver change allow new users to read or write data? Is a sensitive operation still enforced by Lambda? If checkout changes, are webhook signatures preserved and verified correctly? |
These categories describe risk, not file size. A one-line change can have serious consequences if it changes an authorization rule or allows the browser to mark an order as paid.
For example:
- Moving product cards or banners around is usually a frontend change.
- Adding an order page requires checking who can access the order.
- Widening an authorization rule is a backend security change.
- Changing payment processing or order settlement requires reviewing the complete payment flow.
When a change affects more than one category, review it against every relevant category. Do not classify a change as frontend-only just because most of its code is in the frontend.
3. Develop in an Isolated Environment
Keep development work separate from customer traffic. Use a short-lived feature branch and test changes against a local sandbox before deploying them to the live store.
The sandbox is a separate stack in your AWS account, with its own Cognito user pool, test orders, and payment configuration. Customer accounts and production data must remain on the production backend.
The environments serve different purposes:
| Environment | Purpose | What to keep in mind |
|---|---|---|
| Feature branch and local sandbox | Develop and test a change | Use sandbox data, test payment keys, or Mock payments where appropriate |
staging | Test a deployed version on a separate Hosting backend and URL | Use test accounts and test payments; keep the URL private through Amplify Hosting access control |
main | Serve the live store | Use production configuration, the live webhook endpoint, and live payment credentials; keep Mock payments disabled |
The staging branch is connected to AWS Amplify in the same way as main, but it uses a separate Hosting backend and URL. Configure access control in Hosting → Access control to restrict access while testing. The steps are in Custom domain and security.
A single-operator store can skip staging if the deployment process described in Local sandbox is followed. However, changes involving accounts, payments, or the amplify/ directory must still be tested in the sandbox before reaching production.
When staging is available, deploy the change there and verify it before merging it into main.
Keep test and production payment settings separate
The sandbox must use its own test keys or Mock payments, along with a webhook endpoint configured for the sandbox.
The customer-facing store must keep its live payment configuration and live webhook endpoint. Never point a production payment integration at the sandbox webhook or reuse production secrets in development.
4. Review the Diff Before Committing
Before committing a change, review the complete diff on the feature branch. You can use an AI model to help identify risks, but its review is only an aid. It is not a security certification, and it does not replace your own judgment.
Ask the reviewer to answer these questions and point to the relevant lines in the diff:
| Review question | What a useful answer should identify |
|---|---|
| Which security boundaries does this change touch? | Cognito, Stripe or PayPal, schema authorization, webhook handling, secrets, or none of these |
| Does any secret become exposed? | A payment key, webhook secret, SMTP password, or API token entering source control, logs, or browser code |
| Does the change widen access? | Whether a shopper can read another shopper's order or write a field that should only be controlled by Lambda |
| If checkout is affected, is the payment flow still safe? | The correct webhook URL, preserved signature headers, proper verification, and test-only configuration in non-production environments |
Do not accept a review that simply says the code looks fine. Ask for specific findings tied to the changed lines.
Then inspect the diff yourself. Confirm that the change does what you intended, does not introduce unrelated modifications, and respects the security boundaries identified earlier.
If the change affects authentication, payments, authorization, or secrets, resolve the relevant concerns before committing. Do not treat a successful build or a passing frontend test as proof that these security-sensitive paths are correct.
5. Deploy One Stage at a Time
Changes should move through the environments in order. Each stage gives you an opportunity to verify the affected functionality before it reaches customers.
| Stage | What happens | What to verify |
|---|---|---|
| 1. Feature branch and sandbox | Implement the change and test it locally against the sandbox | The affected flow works correctly. Payments use test keys or Mock payments only in this environment. |
2. staging | Deploy the reviewed change to the staging Hosting backend, when available | Test the same flow against the deployed version. Confirm that access control still protects the staging URL. |
3. main | Merge the verified change into production | Confirm that production configuration is correct, live payments use the production endpoint, and Mock payments are disabled. |
Changes involving accounts, payments, authorization, or amplify/ must not go directly from an unreviewed working tree to production.
Commit the reviewed change on its feature branch, verify it in the sandbox, and then promote it through staging when that environment is available. Only merge into main after the relevant checks have passed.
Final Rule
AI can help you write code faster, but you remain responsible for the changes you ship.
Before editing, identify the security boundaries the change could affect. Before committing, review the diff against those boundaries. Before deploying, verify the affected functionality in an isolated environment.
Understand the risk. Review the change. Test it in isolation. Then ship it.
Next step
A worked example of that sequence, from the first prompt through the merge, is in A Practical Guide to AI-Assisted Development.