Warm the pot: Set a large soup pot or Dutch oven over medium heat.
Add 2 tablespoons olive oil and let it shimmer.
Sauté aromatics: Add 1 diced onion, 2 diced carrots, and 2 diced ribs of celery. Cook 6–8 minutes, stirring, until soft and lightly golden. Season with a pinch of salt.
Add garlic and tomato paste: Stir in 4 minced garlic cloves and 1 tablespoon tomato paste.
Cook 1–2 minutes until fragrant and the paste darkens slightly.
Spice it up: Sprinkle in 1 teaspoon dried thyme, 1 teaspoon dried oregano, 1 teaspoon smoked paprika, and a pinch of red pepper flakes if using. Toast for 30 seconds to bloom the spices.
Deglaze and add liquids: Pour in 6 cups low-sodium broth and 1 cup water. Scrape any browned bits from the bottom.
Add 1 bay leaf and the optional Parmesan rind.
Add beans: Stir in two cans of drained, rinsed white beans. Bring to a gentle boil, then reduce to a simmer.
Simmer for flavor: Let the soup simmer uncovered for 15–20 minutes so the flavors meld and the broth gains body.
Blend a little (optional but recommended): For a creamier, protein-rich texture, use an immersion blender to briefly puree 1–2 cups of the soup right in the pot, or ladle into a blender and return. Keep plenty of beans whole for texture.
Add kale: Stir in 5–6 packed cups chopped kale.
Simmer 5–7 minutes until tender but still bright.
Finish with brightness: Turn off the heat. Stir in the zest of 1 lemon and 1–2 tablespoons lemon juice. Add 2–3 tablespoons chopped parsley.
Taste, then season with salt and black pepper as needed.
Serve: Ladle into bowls and drizzle with a bit of olive oil. Top with shaved Parmesan or nutritional yeast if you like. Crusty bread on the side is never a bad idea.