#Secure my deployment

1 messages · Page 1 of 1 (latest)

dim breach
#

im in a process to go to production and make my saas more "secure", i understand that one of the many stesp is to make as much as possible functions internal, so that they are not accessible from outside, and check auth for each public function instead. However to bettter understand who it works, how can i double check that a mutation is not publicacly accessible (kind of additional penetration test)

white nebulaBOT
#

Hi @dim breach. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

To secure your Convex deployment and ensure that certain functions are not publicly accessible, you're on the right track by making functions internal and implementing authentication checks. Here's how you can approach this and verify the security of your mutations:

  1. Use Internal Functions:
    You can use internalMutation instead of mutation to create functions that are only accessible from other Convex functions, not from clients. This is described in the Functions > Internal Functions (https://docs.convex.dev/functions/internal-functions) documentation.

    import { internalMutation } from "./_generated/server";
    
    export const markPlanAsProfessional = internalMutation({
      args: { planId: v.id("plans") },
      handler: async (ctx, args) => {
        await ctx.db.patch(args.planId, { planType: "professional" });
      },
    });
    
  2. Implement Authentication Checks:
    For public functions, implement authentication checks using ctx.auth.getUserIdentity(). This ensures that only authenticated users can access certain functions.

  3. Verification:
    To double-check that a mutation is not publicly accessible, you can try the following:

    a. Use the Convex Dashboard:
    The Dashboard Deployments Functions page (https://docs.convex.dev/dashboard/deployments/functions#running-functions) allows you to see all your functions. Internal functions are marked as such and cannot be run directly from the dashboard.

    b. Client-side Testing:
    Attempt to call the function from your client-side code. If the function is truly internal, this should fail.

    c. Use convex-test:
    You can write tests using the convex-test library to verify that certain functions are not accessible. Here's an example:

#
      import { convexTest } from "convex-test";
      import { test, expect } from "vitest";
      import { internal } from "./_generated/api";
      
      test("internal function is not accessible", async () => {
        const t = convexTest();
        await expect(t.mutation(internal.myFunctions.internalMutation, { a: 1 }))
          .rejects.toThrow();
      });
      ```

   This test attempts to call an internal mutation and expects it to throw an error, confirming that it's not publicly accessible.

4. Additional Security Measures:
   - Use **argument validation** (<https://docs.convex.dev/functions/validation>) for all public functions to prevent unexpected inputs.
   - Implement **row-level security** (<https://stack.convex.dev/row-level-security>) to control access to specific documents based on user permissions.

Remember, security is a multi-layered approach. While making functions internal and implementing authentication checks are important steps, also consider other aspects like data encryption, regular security audits, and keeping your dependencies up to date.

For more detailed best practices on securing your Convex deployment, refer to the **Production > Best Practices** (<https://docs.convex.dev/production/best-practices/#functions>) documentation.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
#

@dim breach Kapa.ai is still learning and improving, please let me know how I did by reacting below.

dim breach
#

@white nebula interesting, what also need to be accounted for a multi user saas, how can i double check proper auth, proper segmentation of data so that userA cannot read userB data, not even by accident

white nebulaBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

To ensure proper authentication and data segmentation in a multi-user SaaS application built with Convex, you need to implement robust access controls and verification mechanisms. Here are some key points to consider and ways to double-check your implementation:

  1. Implement Row-Level Security:
    Use row-level security to ensure that users can only access their own data. You can implement this using custom query and mutation wrappers. The Row Level Security (https://stack.convex.dev/row-level-security) article provides a detailed example of how to do this in Convex.

  2. Use Authentication in Functions:
    Always use ctx.auth.getUserIdentity() in your queries and mutations to identify the user and restrict access accordingly. This is explained in the Authentication in Functions (https://docs.convex.dev/auth/functions-auth) documentation.

  3. Implement Custom Functions:
    Use custom function wrappers to enforce consistent authentication and authorization checks across your application. The Custom Functions (https://stack.convex.dev/custom-functions) article provides examples of how to create these wrappers.

  4. Double-checking proper authentication and data segmentation:

    a. Write Unit Tests:
    Create comprehensive unit tests that attempt to access data belonging to different users. Use the convex-test library to simulate different user contexts and verify that access is properly restricted.

    b. Manual Testing:
    Create multiple test accounts and manually attempt to access data across different accounts. Verify that you can't access or modify data belonging to other users.

    c. Code Review:
    Conduct thorough code reviews to ensure that all functions that access or modify data include proper authentication and authorization checks.

#

d. Use Linting Rules:
Implement custom ESLint rules to enforce the use of authentication checks in all public functions. The ESLint Setup (https://stack.convex.dev/eslint-setup) article provides guidance on how to set this up.

e. Audit Logs:
Implement comprehensive logging for all data access and modification operations. Regularly review these logs to identify any suspicious activities or potential security breaches.

f. Penetration Testing:
Consider conducting or hiring a third party to perform penetration testing on your application to identify any security vulnerabilities.

  1. Additional Security Measures:

Remember, security is an ongoing process. Regularly review and update your security measures as your application evolves and new threats emerge.

For more detailed information on securing your Convex application, refer to the Operational maturity for production (https://stack.convex.dev/operational-maturity-for-production#5-hardening-your-app) guide, which provides a comprehensive list of steps to harden your application.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: