Warm the pot. Set a large pot or Dutch oven over medium heat. Add 2 tablespoons of olive oil.
Sauté the aromatics. Add diced onion, carrots, and celery with a pinch of salt. Cook, stirring occasionally, until softened and lightly golden, about 7–9 minutes.
Add garlic and tomato paste. Stir in the garlic and cook for 30 seconds, just until fragrant.
Add tomato paste and cook for 1–2 minutes to caramelize it slightly.
Build the base. Pour in the crushed or diced tomatoes and scrape up any browned bits on the bottom of the pot. Stir in rosemary, oregano, bay leaf, and a pinch of red pepper flakes if using.
Add beans and broth. Add the cannellini beans and broth. If you have a Parmesan rind, drop it in now.
Bring to a gentle boil, then reduce to a simmer.
Simmer for flavor. Cook uncovered for 15–20 minutes. The soup should thicken slightly and the flavors will meld. Taste and adjust salt and pepper.
Optional texture upgrade. For a creamier body, use a ladle to scoop out 1–2 cups of soup (mostly beans and broth) and blend until smooth, then return it to the pot.
Or lightly mash some beans against the side of the pot with a spoon.
Stir in greens. Add kale or spinach and simmer 2–4 minutes, just until tender and vibrant.
Finish and serve. Remove the bay leaf and Parmesan rind. Stir in lemon juice or a splash of red wine vinegar. Ladle into bowls, drizzle with a little olive oil, and top with grated Parmesan if you like.
Serve with warm crusty bread.